首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QGraphicsRectItem用鼠标移动。怎么做?

QGraphicsRectItem用鼠标移动。怎么做?
EN

Stack Overflow用户
提问于 2016-01-13 15:33:16
回答 1查看 767关注 0票数 0

我有QGraphicsViewQGraphicsSceneQGraphicsRectItemQGraphicsRectItemQGraphicsScene中,最后一个在QGraphicsView中。我只想用鼠标移动QGraphicsRectItem!但是在我的实现中,如果我单击QGraphicsScene上的任何位置,它就会移动。不管是我的QGraphicsRectItem还是其他地方。还有第二个问题。物品已移到现场的中心。再次点击它,它开始从家的位置移动。

代码语言:javascript
复制
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

代码语言:javascript
复制
#include "widget.h"
#include <QApplication>

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

    Steer w;
    w.show();

    return a.exec();
}

widget.h

代码语言:javascript
复制
#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

代码语言:javascript
复制
#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);
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-13 19:38:03

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

代码语言:javascript
复制
#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. 将偏移量重命名为更具描述性的内容。我选择了lastMousePos。不要仅仅在鼠标被按下时更新一次,还要在鼠标被移动时更新它。然后,这只是一个简单的问题,得到两个点之间的差异,并将其添加到项目的位置。
  3. 在对移动事件做出反应之前,检查鼠标是否实际在项目上。如果鼠标没有结束该项目,您需要某种方式来了解这一点,因此需要QPoint(-1, -1)。为此,您可能需要使用单独的布尔标志。这解决了你看到的问题,在那里可以点击场景中的任何地方,让物品移动。 另外,请注意mapFromScene()调用:contains()函数在局部坐标下工作,因此在测试是否在项目上之前,我们必须映射位于场景坐标中的鼠标位置。
  4. 事件函数不是插槽,它们是虚拟的、受保护的函数

您还可以考虑在项目本身中处理这些事件。您不需要在QGraphicsView中执行此操作,特别是当您有多个需要用鼠标拖动的项时。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34770656

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档