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

时间:2017-07-26 19:35:27

标签: c++ crash qt5

我真的在与这个奇怪的虫子争吵了一段时间。我的应用程序甚至在显示小部件之前就崩溃了(但是显示了窗口本身)。这是我的代码:

的main.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();
}

mainwindow.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

mainwindow.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;
}

snakeclass.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

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的新手,这是我的第一个涉及画家和键盘事件的项目。你能帮我弄清楚上面代码中的问题是什么吗?谢谢你的所有答案!

1 个答案:

答案 0 :(得分:1)

  

我的应用程序甚至在显示小部件之前就崩溃了(但是显示了窗口本身)。

它没有崩溃。在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开发人员认为使用库的正确方法。