c++ - 图形场景中的 QMouseEvents 不起作用

标签 c++ qt mousemove qgraphicsitem qgraphicsscene

我是 Qt 的新手,我创建了一个简单的应用程序,该应用程序在自定义 QGraphicsScene 中初始化多个自定义 QGraphicsItems。每个项目都使用随机起始位置和取决于项目位置的权重值进行初始化。在鼠标移动事件中,我希望根据鼠标光标的位置更新项目的权重值

我认为我的 mouseMoveEventgraphicsScene 中无法识别,它在主窗口中似乎工作正常,我在状态栏中实现了一个标签以显示mouseMoveEvents 的数量和 mouseMoveEvent

的 X-Y 位置

代码如下:

自定义图形场景.h:

class ParticleScene : public QGraphicsScene
{
public:
    ParticleScene();

protected: 
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);

private:
    qreal WTotal;
    Particle *particle;

} 

自定义图形场景.cpp:

ParticleScene::ParticleScene()
{

//this->setBackgroundBrush(Qt::gray);
this->setSceneRect(0,0,500,500);

WTotal=0;
int ParticleCount =5;
for (int i =0; i<ParticleCount; i++)
    {
    particle= new Particle();
    particle->StartX= rand()%500;
    particle->StartY= rand()%500;
    particle->W= qSqrt(qPow(particle->StartX,2) + qPow(particle->StartY,2));
    particle->setPos(particle->StartX,particle->StartY);
    this->addItem(particle);
    particle->setFocus();
    WTotal+=particle->W;
    }

}

void ParticleScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    update();
    QGraphicsScene::mouseMoveEvent(event);
}

粒子.h:

我添加了 Keypress 事件 函数,这只移动了添加到场景中的最后一个项目,我假设只有一个项目可以获得焦点。 另一方面,mouseMove 事件 没有做任何事情

class Particle :public QGraphicsItem
{
public:
    Particle();

    QRectF boundingRect() const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    int StartX;
    int StartY;
    qreal W;

protected:
    //added keyPressEvent to test
    virtual void keyPressEvent(QKeyEvent *event);
    virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);

};

粒子.cpp:

Particle::Particle()
{
//    setFlag(ItemIsMovable);
    setFlag(ItemIsFocusable);
}

QRectF Particle::boundingRect() const
{
     return QRect(0,0,120,30);
}

void Particle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    QRectF rec= boundingRect();
    QBrush Brush(Qt::white);

    painter->fillRect(rec,Brush);
    painter->drawText(15,15,"Weight: "+QString::number(W));
    painter->drawRect(rec);

}

void Particle::keyPressEvent(QKeyEvent *event)
{

    switch(event->key()){
    case Qt::Key_Right:{
        moveBy(30,0);
        break;}
    case Qt::Key_Left:{
        moveBy(-30,0);
        break;}
    case Qt::Key_Up:{
        moveBy(0,-30);
        break;}
    case Qt::Key_Down:{
        moveBy(0,30);
        break;}
    }
    update();
}

void Particle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    this->W= this->W / qSqrt(qPow(event->pos().x(),2) + qPow(event->pos().y(),2));
    moveBy(30,0);
    update();
}

MainWindow .h 和 cpp: 此处的状态栏标签正确显示鼠标坐标,即 mouseMoveEvent 在这里起作用

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
   Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    void mouseMoveEvent(QMouseEvent *event);
protected:

private:
    Ui::MainWindow *ui;
    ParticleScene *scene;
    QLabel *statlabel;

    int moves;
};

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

    statlabel=new QLabel(this);
    ui->statusBar->addWidget(statlabel);
    statlabel->setText ("Mouse Coordinates");

    setCentralWidget(ui->graphicsView);
    centralWidget()->setAttribute(Qt::WA_TransparentForMouseEvents);
    ui->graphicsView->setMouseTracking(true);

    scene= new ParticleScene();
    ui->graphicsView->setScene(scene);
    ui->graphicsView->setRenderHint(QPainter::Antialiasing);

    moves=0;

}

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

void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
    moves+=1;
    statlabel->setText("MouseMoves " +QString::number(moves)+ " X:"+QString::number(event->pos().x())+"-- Y:"+QString::number(event->pos().y()));
}

我在导致 mousemoveevent 无法运行的程序中遗漏了什么,有没有办法将所有项目集中在一起?我是否需要将它们放入QList

在程序的下一步中,我希望项目根据所有权重的总和更新它们的权重值,并根据使用新权重值确定新位置的算法移动。

最佳答案

您缺少某种容器,您可以在其中保存所有粒子。在当前的实现中,ParticleScene 将粒子指针作为私有(private)变量。您正在循环中创建多个 Particles(它们是 QGraphicsItem 的),但只有最后一个指针存储在您的自定义场景中。如您所说,您可以使用例如 QList 来保存您的粒子。

此外,我假设您想在场景中移动元素。为此,您还可以自己实现 MousePress 事件(以捕捉何时按下项目以及在什么坐标处),MouseMove(实际移动项目......你已经这样做了,mouseRelease(例如,用于计算权重或发送将触发所有项目权重计算的信号)

与其将所有项目保留在自定义场景中,不如创建一个新类,例如,ItemsManager,其中将存储所有项目和指向场景的指针。在此类中,您可以执行与计算元素重量或其他所需操作有关的所有操作。

关于c++ - 图形场景中的 QMouseEvents 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34119613/

相关文章:

c++ - char *blah = "hello"是如何工作的?

c++ - 如何确定椭圆的旋转角度和opencv中点之间的填充区域,c++

c++ - 从 C 包装器创建 C++ 对象

c++ - 在 c++ 中创建父类(super class)类型的数组以动态存储子类对象

c++ - 配置 Qt .pro 文件以使用 cl.exe 和 link.exe 修复链接错误

java - 移动鼠标时 JPanel FPS 下降

c++ - 使用 qt 完成编程时,在 if 语句之外打印变量数据时遇到问题

android - Qt/Necessitas - 合理的 QFileDialog 替换/皮肤?

javascript - selenium 访问 mouseMove js 函数

javascript 使用拖动来移动元素