C++ QTimer-won';t前进屏幕

C++ QTimer-won';t前进屏幕,c++,qt,qgraphicsscene,qtimer,C++,Qt,Qgraphicsscene,Qtimer,我在dialog.cpp中创建场景,并在my scene.cpp中绘制一些QGraphicsItem。当我将QTimer添加到my dialog.cpp时,每当我将光标移动到场景上以崩溃时,它都会发出提示 dialog.cpp #include "dialog.h" #include "scene.h" #include "ui_dialog.h" #include "instructions.h" #include "settings.h" #include "highscore.h" Di

我在dialog.cpp中创建场景,并在my scene.cpp中绘制一些QGraphicsItem。当我将QTimer添加到my dialog.cpp时,每当我将光标移动到场景上以崩溃时,它都会发出提示

dialog.cpp

#include "dialog.h"
#include "scene.h"
#include "ui_dialog.h"
#include "instructions.h"
#include "settings.h"
#include "highscore.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);

    // Create and configure scene
     scene = new Scene;
     scene->setBackgroundBrush(Qt::black);
     scene->setItemIndexMethod(QGraphicsScene::NoIndex);
     ui->graphicsView->setScene(scene);
     scene->setSceneRect(-200, -150, 400, 300);
     ui->graphicsView->setMouseTracking(true);

     QPixmap tankbase1(":/images/tankbase.jpg");
     ui->tankbaseplay1->setPixmap(tankbase1);

//\/\/\/This is my problem. And not sure why\/\/\/\/\/\/
//     timer = new QTimer(this);
//     QObject::connect(timer, SIGNAL(timeout()), scene, SLOT(advance()));
//     timer->start(10);

}

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

//void Dialog::shoot()
//{

//}


void Dialog::on_startButton_clicked()
{
    ui->settingsButton->hide();
    ui->titlescreen->hide();
    ui->highscoreButton->hide();
    ui->instructionButton->hide();
    ui->startButton->hide();

    QGraphicsTextItem *FirstP;
    QString P1 = "Player1";
    FirstP = scene->addText(P1);
    FirstP->setFont(QFont("Nimbus Mono L", 12,QFont::Bold));
    FirstP->setDefaultTextColor(Qt::white);
    FirstP->setPos(-300, -220);


    QGraphicsTextItem *SecondP;
    QString P2 = "Player2";
    SecondP = scene->addText(P2);
    SecondP->setFont(QFont("Nimbus Mono L", 12,QFont::Bold));
    SecondP->setDefaultTextColor(Qt::white);
    SecondP->setPos(230, -220);
}

void Dialog::on_instructionButton_clicked()
{
    Instructions intDialog;
    intDialog.setModal(true);
    intDialog.exec();
}

void Dialog::on_settingsButton_clicked()
{
    settings intDialog;
    intDialog.setModal(true);
    intDialog.exec();
}


void Dialog::on_highscoreButton_clicked()
{
    highscore intDialog;
    intDialog.setModal(true);
    intDialog.exec();
}
#include "scene.h"
#include <QGraphicsEllipseItem>
#include <QGraphicsLineItem>
#include <QGraphicsSceneMouseEvent>
#include <QTimer>
#include "qmath.h"
#include <math.h>




class GraphicsCircle : public QGraphicsEllipseItem
// class for the fire bullets
{
public:
    GraphicsCircle(qreal dirx, qreal diry)
        : m_Speed(3)
        , m_DirX(dirx)
        , m_DirY(diry)
    {
        setRect(-3.0,-3.0,8.0,8.0);
        setPos(-195, 130);
        QRadialGradient rGrad( 0.0, 0.0, 20.0, 0.0, 0.0);
        rGrad.setColorAt(0.0, QColor(255,255,255));
        rGrad.setColorAt(0.7, QColor(255,255,225));
        rGrad.setColorAt(1.0, QColor(255,0,0,0));
        setBrush(QBrush(rGrad) );
        setPen(QPen(Qt::NoPen));
    }

    virtual ~GraphicsCircle() {}

    void advance(int phase)
    {
        if(!phase) return;
        setPos(x()+m_Speed*m_DirX, y()+m_Speed*m_DirY);
    }

private:
    qreal m_Speed;
    qreal m_DirX;
    qreal m_DirY;
};

Scene::Scene() : QGraphicsScene()
{
    // added the lines below to setup an item, pointing in the positive x direction
    int x1 = 0;
    int y1 = 0;
    cannon = new QGraphicsLineItem(x1, y1, x1 + 50, y1);
    cannon->setPen(QPen(Qt::white, 6));
    this->addItem(cannon);
    cannon->setPos(-195, 130);

    //Create bullets
    m_FireTimer= new QTimer();
    QObject::connect(m_FireTimer, SIGNAL(timeout()), this, SLOT(fire()));
}

void Scene::mousePressEvent(QGraphicsSceneMouseEvent *e)
{
    m_FireTarget = e->scenePos();
    m_FireTimer->start();
    QGraphicsScene::mousePressEvent(e);
}

void Scene::mouseMoveEvent(QGraphicsSceneMouseEvent *e)
{
//    emit mouseMoving(e->scenePos());
//    FirstPlayer->setPos(e->scenePos());

//    qAtan2(cannon->pos(), e->scenePos());

    m_FireTarget = e->scenePos();
    QGraphicsScene::mouseMoveEvent(e);

    QLineF arm(cannon->pos(), e->scenePos());
    cannon->setRotation(360 - arm.angle());


}

void Scene::mouseReleaseEvent ( QGraphicsSceneMouseEvent * e )
{
    m_FireTimer->stop();
    QGraphicsScene::mouseReleaseEvent(e);
}

void Scene::fire()
// creates a fire bullet
// the bullet will move in the direction of the mouse cursor
// the trajectory is sligthly perturbated by a random small angle
{
    qreal dirx = m_FireTarget.x()-195;
    qreal diry = m_FireTarget.y()-195;

    qreal length = sqrt(dirx*dirx+diry*diry);
    if (length!=0)
    {
        // normalized direction vector
        qreal invLength= 1.0/length;
        dirx *= invLength;
        diry *= invLength;

        // creating an angle perturbation of +/- 3°
        qreal alphaPerturbation = static_cast<qreal>(qrand()%6-3) * M_PI / 180.0;
        qreal xPerturbation = cos(alphaPerturbation);
        qreal yPerturbation = sin(alphaPerturbation);
        dirx = dirx*xPerturbation - diry*yPerturbation;            
        diry = diry*xPerturbation + dirx*yPerturbation;

        GraphicsCircle * circle = new GraphicsCircle(dirx, diry);
        addItem(circle);

    }
}

void Scene::advance()
{
   // first remove the pellet out of the sceneRect
    for (int i=0; i<items().count(); ++i)
    {
        QGraphicsItem * item = items().at(i);
        qreal x= item->x();
        qreal y= item->y();
        qreal sx=sceneRect().width();
        qreal sy= sceneRect().height();
        if ( (x < 0.0) || (y < 0.0) || (x > sx) || (y > sy))
        {
            removeItem(item);
            delete item;
        }
    }
    QGraphicsScene::advance();
}
场景.cpp

#include "dialog.h"
#include "scene.h"
#include "ui_dialog.h"
#include "instructions.h"
#include "settings.h"
#include "highscore.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);

    // Create and configure scene
     scene = new Scene;
     scene->setBackgroundBrush(Qt::black);
     scene->setItemIndexMethod(QGraphicsScene::NoIndex);
     ui->graphicsView->setScene(scene);
     scene->setSceneRect(-200, -150, 400, 300);
     ui->graphicsView->setMouseTracking(true);

     QPixmap tankbase1(":/images/tankbase.jpg");
     ui->tankbaseplay1->setPixmap(tankbase1);

//\/\/\/This is my problem. And not sure why\/\/\/\/\/\/
//     timer = new QTimer(this);
//     QObject::connect(timer, SIGNAL(timeout()), scene, SLOT(advance()));
//     timer->start(10);

}

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

//void Dialog::shoot()
//{

//}


void Dialog::on_startButton_clicked()
{
    ui->settingsButton->hide();
    ui->titlescreen->hide();
    ui->highscoreButton->hide();
    ui->instructionButton->hide();
    ui->startButton->hide();

    QGraphicsTextItem *FirstP;
    QString P1 = "Player1";
    FirstP = scene->addText(P1);
    FirstP->setFont(QFont("Nimbus Mono L", 12,QFont::Bold));
    FirstP->setDefaultTextColor(Qt::white);
    FirstP->setPos(-300, -220);


    QGraphicsTextItem *SecondP;
    QString P2 = "Player2";
    SecondP = scene->addText(P2);
    SecondP->setFont(QFont("Nimbus Mono L", 12,QFont::Bold));
    SecondP->setDefaultTextColor(Qt::white);
    SecondP->setPos(230, -220);
}

void Dialog::on_instructionButton_clicked()
{
    Instructions intDialog;
    intDialog.setModal(true);
    intDialog.exec();
}

void Dialog::on_settingsButton_clicked()
{
    settings intDialog;
    intDialog.setModal(true);
    intDialog.exec();
}


void Dialog::on_highscoreButton_clicked()
{
    highscore intDialog;
    intDialog.setModal(true);
    intDialog.exec();
}
#include "scene.h"
#include <QGraphicsEllipseItem>
#include <QGraphicsLineItem>
#include <QGraphicsSceneMouseEvent>
#include <QTimer>
#include "qmath.h"
#include <math.h>




class GraphicsCircle : public QGraphicsEllipseItem
// class for the fire bullets
{
public:
    GraphicsCircle(qreal dirx, qreal diry)
        : m_Speed(3)
        , m_DirX(dirx)
        , m_DirY(diry)
    {
        setRect(-3.0,-3.0,8.0,8.0);
        setPos(-195, 130);
        QRadialGradient rGrad( 0.0, 0.0, 20.0, 0.0, 0.0);
        rGrad.setColorAt(0.0, QColor(255,255,255));
        rGrad.setColorAt(0.7, QColor(255,255,225));
        rGrad.setColorAt(1.0, QColor(255,0,0,0));
        setBrush(QBrush(rGrad) );
        setPen(QPen(Qt::NoPen));
    }

    virtual ~GraphicsCircle() {}

    void advance(int phase)
    {
        if(!phase) return;
        setPos(x()+m_Speed*m_DirX, y()+m_Speed*m_DirY);
    }

private:
    qreal m_Speed;
    qreal m_DirX;
    qreal m_DirY;
};

Scene::Scene() : QGraphicsScene()
{
    // added the lines below to setup an item, pointing in the positive x direction
    int x1 = 0;
    int y1 = 0;
    cannon = new QGraphicsLineItem(x1, y1, x1 + 50, y1);
    cannon->setPen(QPen(Qt::white, 6));
    this->addItem(cannon);
    cannon->setPos(-195, 130);

    //Create bullets
    m_FireTimer= new QTimer();
    QObject::connect(m_FireTimer, SIGNAL(timeout()), this, SLOT(fire()));
}

void Scene::mousePressEvent(QGraphicsSceneMouseEvent *e)
{
    m_FireTarget = e->scenePos();
    m_FireTimer->start();
    QGraphicsScene::mousePressEvent(e);
}

void Scene::mouseMoveEvent(QGraphicsSceneMouseEvent *e)
{
//    emit mouseMoving(e->scenePos());
//    FirstPlayer->setPos(e->scenePos());

//    qAtan2(cannon->pos(), e->scenePos());

    m_FireTarget = e->scenePos();
    QGraphicsScene::mouseMoveEvent(e);

    QLineF arm(cannon->pos(), e->scenePos());
    cannon->setRotation(360 - arm.angle());


}

void Scene::mouseReleaseEvent ( QGraphicsSceneMouseEvent * e )
{
    m_FireTimer->stop();
    QGraphicsScene::mouseReleaseEvent(e);
}

void Scene::fire()
// creates a fire bullet
// the bullet will move in the direction of the mouse cursor
// the trajectory is sligthly perturbated by a random small angle
{
    qreal dirx = m_FireTarget.x()-195;
    qreal diry = m_FireTarget.y()-195;

    qreal length = sqrt(dirx*dirx+diry*diry);
    if (length!=0)
    {
        // normalized direction vector
        qreal invLength= 1.0/length;
        dirx *= invLength;
        diry *= invLength;

        // creating an angle perturbation of +/- 3°
        qreal alphaPerturbation = static_cast<qreal>(qrand()%6-3) * M_PI / 180.0;
        qreal xPerturbation = cos(alphaPerturbation);
        qreal yPerturbation = sin(alphaPerturbation);
        dirx = dirx*xPerturbation - diry*yPerturbation;            
        diry = diry*xPerturbation + dirx*yPerturbation;

        GraphicsCircle * circle = new GraphicsCircle(dirx, diry);
        addItem(circle);

    }
}

void Scene::advance()
{
   // first remove the pellet out of the sceneRect
    for (int i=0; i<items().count(); ++i)
    {
        QGraphicsItem * item = items().at(i);
        qreal x= item->x();
        qreal y= item->y();
        qreal sx=sceneRect().width();
        qreal sy= sceneRect().height();
        if ( (x < 0.0) || (y < 0.0) || (x > sx) || (y > sy))
        {
            removeItem(item);
            delete item;
        }
    }
    QGraphicsScene::advance();
}
#包括“scene.h”
#包括
#包括
#包括
#包括
#包括“qmath.h”
#包括
类GraphicsCircle:public QGraphicsEllipseItem
//子弹射击课
{
公众:
图形循环(qreal-dirx,qreal-diry)
:m_速度(3)
,m_DirX(DirX)
,m_DirY(DirY)
{
setRect(-3.0,-3.0,8.0,8.0);
setPos(-195130);
qradialgradientrgrad(0.0,0.0,20.0,0.0,0.0);
rGrad.setColorAt(0.0,QColor(255255));
rGrad.setColorAt(0.7,QColor(255255225));
rGrad.setColorAt(1.0,QColor(255,0,0));
立根丛(QBrush(rGrad));
setPen(QPen(Qt::NoPen));
}
虚拟~GraphicsCircle(){}
无效提前(int阶段)
{
如果(!阶段)返回;
setPos(x()+m_速度*m_方向,y()+m_速度*m_方向);
}
私人:
qreal m_速度;
qreal m_DirX;
qreal m_DirY;
};
场景::场景():qgraphicscene()
{
//添加以下行以设置项目,指向正x方向
int-x1=0;
int y1=0;
cannon=新的QGraphicsLineItem(x1,y1,x1+50,y1);
cannon->setPen(QPen(Qt::白色,6));
本->附加项(加农炮);
加农炮->设置位置(-195130);
//制造子弹
m_FireTimer=新的QTimer();
QObject::connect(m_FireTimer,信号(timeout()),this,插槽(fire());
}
无效场景::MousePresseEvent(QGraphicsSceneMouseEvent*e)
{
m_FireTarget=e->scenePos();
m_FireTimer->start();
qgraphicscene::mousePressEvent(e);
}
void场景::mouseMoveEvent(QGraphicsSceneMouseEvent*e)
{
//发射鼠标移动(e->scenePos());
//FirstPlayer->setPos(e->scenePos());
//qAtan2(加农炮->位置(),e->场景();
m_FireTarget=e->scenePos();
qgraphicscene::mouseMoveEvent(e);
QLineF臂(加农炮->位置(),e->场景();
加农炮->设置旋转(360臂角度());
}
无效场景::mouseReleaseEvent(QGraphicsSceneMouseEvent*e)
{
m_FireTimer->stop();
qgraphicscene::mouseReleaseEvent(e);
}
虚空场景::火()
//制造一颗火弹
//项目符号将沿鼠标光标的方向移动
//轨迹受到随机小角度的轻微扰动
{
qreal dirx=m_FireTarget.x()-195;
qreal diry=m_FireTarget.y()-195;
qreal length=sqrt(dirx*dirx+diry*diry);
如果(长度!=0)
{
//归一化方向向量
qreal invLength=1.0/长度;
dirx*=invLength;
diry*=长度;
//产生+/-3°的角度扰动
qreal=静态(qrand()%6-3)*M_PI/180.0;
qreal xperturbanation=cos(α扰动);
qreal-yperturation=sin(α扰动);
dirx=dirx*xperturbanation-diry*yperturbanation;
diry=diry*xperturbanation+dirx*yperturbanation;
GraphicsCircle*圆=新的GraphicsCircle(dirx,diry);
附加项(圆圈);
}
}
void场景::advance()
{
//首先,将颗粒从容器中取出
对于(int i=0;ix();
qreal y=项目->y();
qreal sx=sceneright().width();
qreal sy=sceneright().height();
if((x<0.0)| |(y<0.0)| |(x>sx)| |(y>sy))
{
移除项目(项目);
删除项目;
}
}
qgraphicscene::advance();
}
当我在dialog.cpp中运行没有QTimer代码的代码时,它会运行,我的QGraphicsItem会显示并相应移动。当我添加QTimer时,QGraphicsItem会消失。完全不知道问题所在

此外,我还获取了场景代码,并单独运行了它,它可以正常工作。唯一的区别是场景和QTimer是在main.cpp中创建的


非常需要帮助!!!!

在删除列表中的项目时,您正在对项目列表进行迭代。这听起来很麻烦

我认为这可能会使您的
advance()
函数更简洁

QList <QGraphicsItem *> itemsToRemove;
foreach( QGraphicsItem * item, this->items() )
{
    if( !this->sceneRect().intersects(item->boundingRect()) )
    {
        // The item is no longer in the scene rect, get ready to delete it
        itemsToRemove.append(item);
    }
}

foreach( QGraphicsItem * item, itemsToRemove )
{
    this->removeItem(item);
    delete(item);
}
QList itemsToRemove;
foreach(QGraphicsItem*item,this->items())
{
如果(!this->scen直立().相交(item->boundingRect())
{
//该项目不再位于场景矩形中,请准备将其删除
itemsToRemove.append(项目);
}
}
foreach(QGraphicsItem*item,itemsToRemove)
{
此->删除项目(项目);
删除(项目);
}
同时阅读QGraphicscene的说明

有许多辅助方法可以使查找某个区域中的项目或一个项目与另一个项目冲突变得更容易


希望这能有所帮助。

当您遇到此类问题时,很高兴看到崩溃的回溯。感谢您和其他人,您必须引用scen直立()。因为它是非指针类型,所以相交。