繁体   English   中英

QGraphicsRectItem用鼠标移动。 如何?

[英]QGraphicsRectItem move with mouse. How to?

我有QGraphicsViewQGraphicsSceneQGraphicsRectItem QGraphicsRectItemQGraphicsScene和最后的位置上QGraphicsView 我只想通过单击鼠标来移动QGraphicsRectItem 但是在我的实现中,如果我单击QGraphicsScene上的任何位置,它都会移动。 无论是我的QGraphicsRectItem还是其他地方。 第二个问题。 该项目已移动到场景的中心。 再次单击它,它将开始从家庭位置移动。

void Steer::mousePressEvent(QMouseEvent *click)
{
    offset = click->pos();
}

void Steer::mouseMoveEvent(QMouseEvent *event)
{
    if(event->buttons() & Qt::LeftButton)
    {
       p1->setPos(event->localPos() - offset); //p1 movable item
    }
}

我做错了什么?

更新:

main.cpp

#include "widget.h"
#include <QApplication>

    int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    Steer w;
    w.show();

    return a.exec();
}

widget.h

#ifndef STEER_H
#define STEER_H

#include <QGraphicsView>
#include <QGraphicsScene>
#include <QMouseEvent>
#include <QPoint>
#include <QGraphicsRectItem>

class Steer : public QGraphicsView
{
    Q_OBJECT

private:
    QGraphicsScene *scene;
    QGraphicsRectItem *p1;

    QPoint offset;

public:
   explicit  Steer(QGraphicsView *parent = 0);
    ~Steer(){}

public slots:
    void mousePressEvent(QMouseEvent * click);
    void mouseMoveEvent(QMouseEvent * event);
};

#endif // STEER_H

widget.cpp

#include "widget.h"
#include <QBrush>

Steer::Steer(QGraphicsView *parent)
    : QGraphicsView(parent)
{
    scene = new QGraphicsScene;
    p1 = new QGraphicsRectItem;

    //add player
    p1->setRect(760, 160, 10, 80);

    //add scene
    scene->setSceneRect(0, 0, 800, 400);

    //add moveable item
    scene->addItem(p1);

    //set scene
    this->setScene(scene);
    this->show();
}

void Steer::mousePressEvent(QMouseEvent *click)
{
    offset = click->pos();
}

void Steer::mouseMoveEvent(QMouseEvent *event)
{
    if(event->buttons() & Qt::LeftButton)
    {
       p1->setPos(event->localPos() - offset);
    }
}

我会尝试另一种更容易理解的方法:

#include <QtWidgets>

class Steer : public QGraphicsView
{
public:
    Steer()
    {
        scene = new QGraphicsScene;
        p1 = new QGraphicsRectItem;

        //add player
        p1->setRect(0, 0, 10, 80);
        p1->setX(760);
        p1->setY(160);

        //add scene
        scene->setSceneRect(0, 0, 800, 400);

        //add moveable item
        scene->addItem(p1);

        //set scene
        this->setScene(scene);
        this->show();
    }

protected:
    void mousePressEvent(QMouseEvent * click)
    {
        if (p1->contains(p1->mapFromScene(click->localPos()))) {
            lastMousePos = click->pos();
        } else {
            lastMousePos = QPoint(-1, -1);
        }
    }

    void mouseMoveEvent(QMouseEvent * event)
    {
        if(!(event->buttons() & Qt::LeftButton)) {
            return;
        }

        if (lastMousePos == QPoint(-1, -1)) {
            return;
        }

        p1->setPos(p1->pos() + (event->localPos() - lastMousePos));
        lastMousePos = event->pos();
    }

private:
    QGraphicsScene *scene;
    QGraphicsRectItem *p1;

    QPoint lastMousePos;
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    Steer w;
    w.show();

    return a.exec();
}

这里有几件事要指出:

  1. 不要使用setRect()设置QGraphicsRectItem的位置。 不像您认为的那样起作用 始终使用setPos()更改项目的位置。

  2. 将offset重命名为更具描述性的名称。 我选择了lastMousePos 不仅要在按下鼠标时更新一次,还应在移动鼠标时更新它。 然后,仅需获取两点之间的差异并将其添加到项目的位置即可。

  3. 在对移动事件做出反应之前,请检查鼠标是否确实在该项目上。 如果鼠标不在该项目上,则需要某种了解方式,因此需要QPoint(-1, -1) 您可能需要为此使用单独的布尔标志。 这解决了您所看到的问题,可以在场景中的任何位置单击以移动项目。

    另外,请注意mapFromScene()调用: contains()函数可在局部坐标下工作,因此在测试鼠标是否位于项目上方之前,我们必须先映射场景坐标中的鼠标位置。

  4. 事件函数不是插槽,它们是虚拟的,受保护的函数


您也可以考虑在项目本身中处理这些事件。 您无需从QGraphicsView内进行操作,尤其是当您需要用鼠标拖动其中多个项目时,尤其如此。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM