【已解决】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进行投诉反馈,一经查实,立即删除!