QGraphicsRectItem随鼠标移动。怎么样?

时间:2016-01-13 15:33:16

标签: c++ qt move

我有QGraphicsViewQGraphicsSceneQGraphicsRectItemQGraphicsRectItem中的QGraphicsSceneQGraphicsView中的最后一个QGraphicsRectItem。我想通过点击它来移动QGraphicsRectItem鼠标!但是在我的实现中,如果我点击QGraphicsScene上的任何位置,它就会移动。无论是我的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); } }

guess

1 个答案:

答案 0 :(得分:1)

我尝试了一种更容易理解的不同方法:

#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的位置。它doesn't work你认为可能的方式。始终使用setPos()更改项目的位置。

  2. 将偏移重命名为更具描述性的内容。我选择lastMousePos。不是在按下鼠标时只更新一次,而是在移动鼠标时更新它。然后,只需要获得两点之间的差异并将其添加到项目的位置。

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

    另外,请注意mapFromScene()调用:contains()函数在本地坐标中工作,因此我们必须在测试之前映射场景坐标中的鼠标位置,如果它在项目上方。

  4. 事件功能不是广告位,而是virtual, protected functions

  5. 您还可以考虑在项目中处理这些事件。您不需要在QGraphicsView内执行此操作,尤其是如果您需要使用鼠标拖动这些项目中的多个项目。