【已解决】Qt mouseMoveEvent、mouseReleaseEvent失效无法触发
问题背景
我有一个派生自QGraphicsObject
的类,这个类其实就是同时继承了QGraphicsItem
和QObject
的类
相当于在QGraphicsItem
的基础上增加了事件消息的功能
我派生出来的这个类主要是实现了由多个点组成的多边形
现在想实现一个功能,拖动其中的某个点,改变多边形的形状
目标点已获得
只需要重写mousePressEvent
、mouseMoveEvent
、mouseReleaseEvent
实现具体逻辑就可以了
问题
hoverMoveEvent
、mousePressEvent
都可以正常触发,但是mouseMoveEvent
、mouseReleaseEvent
怎么都触发不了
原因
先看看原本的代码,尤其关注mousePressEvent
void TriangleItem::mousePressEvent(QGraphicsSceneMouseEvent* evt)
{
_handleIndex = _activeIndex;
QGraphicsObject::mousePressEvent(evt);
}
void TriangleItem::mouseMoveEvent(QGraphicsSceneMouseEvent* evt)
{
if (!_isFinished || _handleIndex < 0) {
QGraphicsObject::mouseMoveEvent(evt);
return;
}
QPointF p = evt->pos();
// 相关处理逻辑
// ...
QGraphicsObject::mouseMoveEvent(evt);
}
void TriangleItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* evt)
{
_handleIndex = -1;
QGraphicsObject::mouseReleaseEvent(evt)
}
我在mousePressEvent
逻辑实现完后,直接调用了父类的事件处理函数QGraphicsObject::mousePressEvent(evt)
,把事件交由父类处理,没有accept
在看Qt GraphicsItem mousePressEvent文档中的描述
翻译后大概意思:
对于事件事件,可以重新实现此事件处理程序以接收此项目的鼠标按下事件。鼠标按下事件仅传递给接受按下的鼠标按钮的项目。默认情况下,一个项目接受所有鼠标按钮,但您可以通过调用
setAcceptedMouseButtons()
来更改这一点。
鼠标按下事件决定哪个项目应该成为鼠标抓取器(请参阅QGraphicsScene::mouseGrabberItem()
)。如果不重新实现此功能,按下事件将传播到该项目下的任何最上面的项目,并且不会向该项目传递其他鼠标事件。
若重新实现此函数,则默认情况下会接受事件(请参见QEvent::accept()
),并且此项就是鼠标抓取器。这允许项目接收未来的移动、释放和双击事件。如果对事件调用QEvent::ignore()
,则此项将失去鼠标抓取,并且事件将传播到下面任何最顶层的项。除非收到新的鼠标按下事件,否则不会向该项目传递更多的鼠标事件。
默认实现处理基本的项交互,如选择和移动。如果您想在重新实现此函数时保留基本实现,请在重新实现中调用QGraphicsItem::mousePressEvent()
。
对于既不可移动也不可选择的项,事件为QEvent::ignore()
。
也就是说,如果不accept
,那么这个对象就没法接收移动、释放和双击事件
解决
知道了原因就好办
问题出在mousePressEvent
,如果确认了需要移动的点,那么就需要accept
事件,以允许后续mouseMoveEvent
、mouseReleaseEvent
可以被正常触发
void TriangleItem::mousePressEvent(QGraphicsSceneMouseEvent* evt)
{
if (_activeIndex >= 0) {
_handleIndex = _activeIndex;
evt->accept();
}
else {
evt->ignore();
}
}
void TriangleItem::mouseMoveEvent(QGraphicsSceneMouseEvent* evt)
{
if (!_isFinished || _handleIndex < 0) {
QGraphicsObject::mouseMoveEvent(evt);
return;
}
QPointF p = evt->pos();
// 相关处理逻辑
QGraphicsObject::mouseMoveEvent(evt);
}
void TriangleItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* evt)
{
if (_handleIndex >= 0) {
_handleIndex = -1;
}
else {
evt->ignore();
}
}
相关内容
QGraphicsItem::mouseReleaseEvent文档也描述了这一点,要想触发mouseReleaseEvent
,必须在mousePressEvent
中accept
事件
对于事件事件,可以重新实现此事件处理程序以接收此项的鼠标释放事件。
对事件调用QEvent::ignore()
或QEvent::accept()
无效。
默认实现处理基本的项交互,如选择和移动。如果您想在重新实现此函数时保留基本实现,请在重新实现中调用QGraphicsItem::mouseReleaseEvent()
。
请注意,mousePressEvent()
决定接收鼠标事件的图形项。有关详细信息,请参阅mousePressEvent()
描述。
mouseDoubleClickEvent
、mouseMoveEvent
也都是一样的描述
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!