c++ - Qt5 C++ 应用程序因未知原因崩溃

标签 c++ crash qt5

<分区>

一段时间以来,我一直在为那个奇怪的错误而苦苦挣扎。我的应用程序甚至在显示小部件之前就崩溃了(但显示了窗口本身)。这是我的代码:

主要.cpp

#include "mainwindow.h"
#include <QApplication>
#include <QTimer>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.setWindowTitle("Snake");
    w.resize(500, 500);
    w.show();
    QTimer* timer = new QTimer();
    while(!w.checkCollision())
    {
        if(timer -> isActive() == false)
        {
            w.play();
            timer -> start(1);
        }
    }
    return a.exec();
}

主窗口.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPainter>
#include <QKeyEvent>
#include <QDebug>
#include <snakeclass.h>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    Snake snake;
    void paintEvent(QPaintEvent*);
    void keyEvent(QKeyEvent* keyevent);
    void move();
    bool checkCollision();
    void play();
    ~MainWindow();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

主窗口.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPainter>
#include <QPainterPath>
#include <QKeyEvent>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{

}

void MainWindow::paintEvent(QPaintEvent*)
{
    QPainter painter(this);
    // Draw black background.
    painter.drawRect(0, 0, 500, 500);
    painter.fillRect(0, 0, 500, 500, Qt::black);
    for(unsigned int i = 0; i < snake.getLength(); i++)
    {
        // Draw green snake's body.
        painter.setPen(Qt::green);
        painter.setBrush(Qt::green);
        // If i = 0, so if we are drawing snake's head.
        if(i == 0)
        {
            // Draw red head.
            painter.setPen(Qt::red);
            painter.setBrush(Qt::red);
        }
        painter.drawEllipse((snake.getDot(i)).x, (snake.getDot(i)).y, 10, 10);
    }
}

void MainWindow::keyEvent(QKeyEvent* keyevent)
{
    if(keyevent -> key() == Qt::Key_Left)
    {
        if(snake.getDirection() != Snake::Direction::RIGHT)
        {
            snake.setDirection(Snake::Direction::LEFT);
        }
    }
    else if(keyevent -> key() == Qt::Key_Right)
    {
        if(snake.getDirection() != Snake::Direction::LEFT)
        {
            snake.setDirection(Snake::Direction::RIGHT);
        }
    }
    else if(keyevent -> key() == Qt::Key_Up)
    {
        if(snake.getDirection() != Snake::Direction::DOWN)
        {
            snake.setDirection(Snake::Direction::UP);
        }
    }
    else if(keyevent -> key() == Qt::Key_Down)
    {
        if(snake.getDirection() != Snake::Direction::UP)
        {
            snake.setDirection(Snake::Direction::DOWN);
        }
    }
}

void MainWindow::move()
{
    for(unsigned int i = snake.getLength(); i > 0; i--)
    {
        snake.editDot((snake.getDot(i - 1)).x, (snake.getDot(i - 1)).y, i, (snake.getDot(i - 1)).direction);
    }
    if(snake.getDirection() == Snake::Direction::UP)
    {
        if(int(snake.getDot(0).y - 10) < 0)
        {
            snake.editDot((snake.getDot(0)).x, 500, 0, snake.getDirection());
        }
        else
        {
            snake.editDot((snake.getDot(0)).x, (snake.getDot(0)).y - 10, 0, snake.getDirection());
        }
    }
    else if(snake.getDirection() == Snake::Direction::DOWN)
    {
        if(((snake.getDot(0)).y + 10) > 490)
        {
            snake.editDot((snake.getDot(0)).x, 0, 0, snake.getDirection());
        }
        else
        {
            snake.editDot((snake.getDot(0)).x, (snake.getDot(0)).y + 10, 0, snake.getDirection());
        }
    }
    else if(snake.getDirection() == Snake::Direction::RIGHT)
    {
        if(((snake.getDot(0)).x + 10) > 490)
        {
            snake.editDot(0, (snake.getDot(0)).y, 0, snake.getDirection());
        }
        else
        {
            snake.editDot((snake.getDot(0)).x + 10, (snake.getDot(0)).y, 0, snake.getDirection());
        }
    }
    else if(snake.getDirection() == Snake::Direction::LEFT)
    {
        if((int((snake.getDot(0)).x) - 10) < 0)
        {
            snake.editDot(500, (snake.getDot(0)).y, 0, snake.getDirection());
        }
        else
        {
            snake.editDot((snake.getDot(0)).x - 10, (snake.getDot(0)).y, 0, snake.getDirection());
        }
    }
}

bool MainWindow::checkCollision()
{
    for(unsigned int i = 0; i < snake.getLength(); i++)
    {
        for(unsigned int j = 0; j < snake.getLength(); j++)
        {
            if((i != j) && ((snake.getDot(i)).x == (snake.getDot(j)).x) && ((snake.getDot(i)).y == (snake.getDot(j)).y))
            {
                return true;
            }
        }
    }
    return false;
}

void MainWindow::play()
{
    //move();
    update();
}

MainWindow::~MainWindow()
{
    delete ui;
}

蛇类.h

    #ifndef SNAKECLASS
    #define SNAKECLASS

    #include <vector>

    class Snake
    {
        public:

            enum class Direction
            {
                LEFT,
                RIGHT,
                UP,
                DOWN
            };

            // Dot is a part of the snake.
            struct dot
            {
                unsigned int x;
                unsigned int y;
                // Number of the dot (head is 0).
                unsigned int dotNumber;
                // Direction of the particular dot.
                Direction direction;
            };

            unsigned int getLength();
            unsigned int getScore();
            unsigned int getSpeed();
            Direction getDirection();
            dot getDot(unsigned int dotNumber);

            void setLength(unsigned int length);
            void setScore(unsigned int score);
            void setSpeed(unsigned int speed);
            void setDirection(Direction direction);
            // Returns new dot's dotNumber.
            unsigned int newDot();
            void editDot(unsigned int x, unsigned int y, unsigned int dotNumber, Direction direction);

        private:

            unsigned int length = 3;
            unsigned int score = 0;
            unsigned int speed = 1;
            Direction direction = Direction::RIGHT;
            std::vector <dot> dots = {dot {250, 250, 0, Direction::RIGHT},
                                      dot {240, 250, 1, Direction::RIGHT},
                                      dot {230, 250, 2, Direction::RIGHT}};
    };

    #endif // SNAKECLASS

蛇类.cpp

#include "snakeclass.h"

unsigned int Snake::getLength()
{
    return length;
}

unsigned int Snake::getScore()
{
    return score;
}

unsigned int Snake::getSpeed()
{
    return speed;
}

Snake::Direction Snake::getDirection()
{
    return direction;
}

Snake::dot Snake::getDot(unsigned int dotNumber)
{
    return dots.at(dotNumber);
}

void Snake::setLength(unsigned int length)
{
    this -> length = length;
}

void Snake::setScore(unsigned int score)
{
    this -> score = score;
}

void Snake::setSpeed(unsigned int speed)
{
    this -> speed = speed;
}

void Snake::setDirection(Snake::Direction direction)
{
    this -> direction = direction;
}

unsigned int Snake::newDot()
{
    dot newDot;
    newDot.dotNumber = dots.size();
    dots.push_back(newDot);
    length ++;
    return newDot.dotNumber;
}

void Snake::editDot(unsigned int x, unsigned int y, unsigned int dotNumber, Snake::Direction direction)
{
    for(unsigned int i = 0; i < dots.size(); i++)
    {
        if((dots.at(i)).dotNumber == dotNumber)
        {
            dots.at(i).x = x;
            dots.at(i).y = y;
            dots.at(i).direction = direction;
        }
    }
}

我是 Qt5 的新手,这是我的第一个涉及画家和键盘事件的项目。你能帮我弄清楚上面代码中的问题是什么吗?谢谢大家的回答!

最佳答案

My application crashes even before widgets are shown (but window itself is shown).

它不会崩溃。在 main.cpp 中有一个无限循环,其中一些结果是预期的,即 !w.checkCollision(),但是由于 中没有运行事件循环main.cpp 没有任何反应,程序卡在那里徒劳等待。

作为对您问题的回答,为了查看小部件,请按以下方式添加 QApplication::processEvents();:

while(!w.checkCollision())
{
    QApplication::processEvents();

    if(timer -> isActive() == false)
    {
        w.play();
        timer -> start(1);
    }
}

但是,使用这种方法您将面临更多问题。因此,我强烈建议您查看 Qt Creator 中的示例,以了解哪种是 Qt 开发人员所认为的使用该库的正确方法。

关于c++ - Qt5 C++ 应用程序因未知原因崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45335974/

相关文章:

c++ - 我应该将项目的哪些文件放入 repo

core-data - -[NSCFDictionary initWithObjects :forKeys:count:]: attempt to insert nil value at objects[0] (key: sourceRelationship)

python-3.x - 虽然true循环给我递归错误

c++ - 使用 QMetaType 的反射(按名称实例化类)

qt - 如何禁用或缩短 QTableView 中的工具提示延迟?

c++ - msvc 和 clang 中的函数调用不明确,但 gcc 中没有

c++ - 如何从 Boost.PropertyTree 复制子树

c++ - 缩小从 unsigned 到 double 的转换

iphone - 转到上一个 ViewController 时应用程序崩溃

qt - QCursor::pos();呈现错误的坐标