在我的应用程序中,我尝试用线连接节点。我使用QGraphicsView和QGraphicsScene以及我自己的QGraphicsItems。现在,如果我点击一个项目,我想绘制一条线到另一个节点。为了给出视觉反馈,如果鼠标悬停在目标上,则目标应该改变颜色。到目前为止基础工作,但我的问题是,如果我用鼠标拖动一行(通过mouseMoveEvent),我不再得到任何hoverEvents。我用这段代码复制了行为:
标题文件:
#pragma once
#include <QtWidgets/Qwidget>
#include <QGraphicsItem>
#include <QGraphicsScene>
class HaggiLearnsQt : public QWidget
{
Q_OBJECT
public:
HaggiLearnsQt(QWidget *parent = Q_NULLPTR);
};
class MyScene : public QGraphicsScene
{
public:
MyScene(QObject* parent = 0);
void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent);
};
class MyItem : public QGraphicsItem
{
public:
MyItem(QGraphicsItem* parent = Q_NULLPTR);
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
bool mouseOverItem;
};
实现:
#include "HaggiLearnsQt.h"
#include <QMessageBox>
#include <QFrame>
#include <QHBoxLayout>
#include <QGraphicsView>
MyScene::MyScene(QObject* parent)
{}
void MyScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
QGraphicsScene::mouseMoveEvent(mouseEvent);
}
MyItem::MyItem(QGraphicsItem* parent) : mouseOverItem(false)
{
setAcceptHoverEvents(true);
}
QRectF MyItem::boundingRect() const
{
return QRectF(-50, -50, 50, 50);
}
void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
QBrush b = QBrush(Qt::black);
if(mouseOverItem)
b = QBrush(Qt::yellow);
painter->setBrush(b);
painter->drawRect(boundingRect());
}
void MyItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
mouseOverItem = true;
QGraphicsItem::hoverEnterEvent(event);
}
void MyItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
mouseOverItem = false;
QGraphicsItem::hoverLeaveEvent(event);
}
HaggiLearnsQt::HaggiLearnsQt(QWidget *parent)
: QWidget(parent)
{
QHBoxLayout* layout = new QHBoxLayout(this);
MyScene* graphicsScene = new MyScene();
QGraphicsView* graphicsView = new QGraphicsView();
graphicsView->setRenderHint(QPainter::RenderHint::Antialiasing, true);
graphicsView->setScene(graphicsScene);
layout->addWidget(graphicsView);
graphicsView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
graphicsView->setMinimumHeight(200);
graphicsView->setMinimumWidth(200);
graphicsView->setStyleSheet("background-color : gray");
MyItem* myitem = new MyItem();
myitem->setPos(50, 50);
graphicsScene->addItem(myitem);
}
默认的main.cpp:
#include "HaggiLearnsQt.h"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
HaggiLearnsQt w;
w.show();
return a.exec();
}
如果您运行代码,窗口中间会出现一个框。如果将鼠标悬停在框上,则会改变颜色。现在尝试在框外滑动并按下按钮进入框中。该框不会收到悬停,也不会改变颜色。
所以我的问题是:当我用按下的按钮移动鼠标时,我可以以某种方式更改项目吗?
答案 0 :(得分:1)
您可以通过mouseEvent->scenePos()
将hovered项目传递给场景鼠标移动事件处理程序中的QGraphicsScene::itemAt
方法。
在MyItem
中有指向MyScene
实例的指针:
class MyScene : public QGraphicsScene
{
MyItem * hovered;
//...
在MyScene构造函数中将其初始化为零:
MyScene::MyScene(QObject* parent)
{
hovered = 0;
}
然后用它来跟踪当前突出显示的项目(如果有的话):
void MyScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
if(mouseEvent->buttons())
{
QGraphicsItem * item = itemAt(mouseEvent->scenePos(), QTransform());
MyItem * my = dynamic_cast<MyItem*>(item);
if(my != 0)
{
qDebug() << mouseEvent->scenePos();
if(!my->mouseOverItem)
{
my->mouseOverItem = true;
my->update();
hovered = my;
}
}
else
{
if(hovered != 0)
{
hovered->mouseOverItem = false;
hovered->update();
hovered = 0;
}
}
}
QGraphicsScene::mouseMoveEvent(mouseEvent);
}
如果没有按住鼠标按钮,则开头的行if(mouseEvent->buttons())
会阻止执行检查。
不要忘记在MyItem构造函数中将mouseOverItem初始化为false:
MyItem::MyItem(QGraphicsItem* parent) : mouseOverItem(false)
{
setAcceptHoverEvents(true);
mouseOverItem = false;
}