QGraphicsRectItem 随鼠标移动.如何
QGraphicsRectItem move with mouse. How to?
我有QGraphicsView
,QGraphicsScene
和QGraphicsRectItem
。 QGraphicsRectItem
在QGraphicsScene
和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();
}
这里有几点需要指出:
不要使用
setRect()
来设置QGraphicsRectItem
的位置。它不像你想象的那样工作。始终使用setPos()
更改项目的位置。将偏移量重命名为更具描述性的名称。我选择了
lastMousePos
.不要只在按下鼠标时更新一次,还要在移动鼠标时更新它。然后,只需获取两点之间的差异并将其添加到项目的位置即可。在对移动事件做出反应之前,检查鼠标是否实际位于项目上。如果鼠标不在项目上,则需要某种方法来知道这一点,因此
QPoint(-1, -1)
.为此,您可能希望使用单独的布尔标志。这解决了您看到的问题,可以单击场景中的任意位置以移动项目。另外,请注意
mapFromScene()
调用:contains()
函数在本地坐标中工作,因此我们必须在测试它是否在项目上方之前映射场景坐标中的鼠标位置。事件函数不是插槽,它们是虚拟的、受保护的函数。
您还可以考虑在项目本身中处理这些事件。您不需要从 QGraphicsView
内执行此操作,特别是如果您有多个需要用鼠标拖动的这些项目。
- 如何从具有移动语义的类对象中生成共享指针
- 移动赋值运算符;尝试引用已删除的函数.我该如何解决这个问题?
- 如何使用 GPS 和指南针开发点移动算法
- 如何移动QListWidgetItem?
- 当调用FREAD()函数时,文件指针如何移动
- 如何移动 TArray 的内容
- 我可以在 std::list 中移动元素而不会使迭代器或引用无效,但是如何移动呢?
- QT-如何移动文件
- 如何移动 std::ostringstream 的底层字符串对象?
- 如何移动等距线-三条平行线(3d)的情况
- 如何移动内部有承诺的结构
- lambda是如何移动的
- 如何移动std::ostream
- Cython:如何移动大型对象而不复制它们
- 如何移动到文件夹并执行Windows命令行调用
- Std::bind和unique_ptr语言 - 如何移动
- Qt:如何移动textit光标到特定的冷和行
- 如何移动数组中的元素,将奇数放到数组的开头(从最小到最大),甚至放到后面(从最大到最小)
- 如何移动std::unique_ptr作为构造函数参数
- 如何移动语义工作与unique_ptr