【已解决】Qt mouseMoveEvent、mouseReleaseEvent失效无法触发

问题背景

我有一个派生自QGraphicsObject的类,这个类其实就是同时继承了QGraphicsItemQObject的类

相当于在QGraphicsItem的基础上增加了事件消息的功能

我派生出来的这个类主要是实现了由多个点组成的多边形

现在想实现一个功能,拖动其中的某个点,改变多边形的形状

目标点已获得

只需要重写mousePressEventmouseMoveEventmouseReleaseEvent实现具体逻辑就可以了

问题

hoverMoveEventmousePressEvent都可以正常触发,但是mouseMoveEventmouseReleaseEvent怎么都触发不了

原因

先看看原本的代码,尤其关注mousePressEvent

cpp 复制代码
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事件,以允许后续mouseMoveEventmouseReleaseEvent可以被正常触发

cpp 复制代码
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,必须在mousePressEventaccept事件

对于事件事件,可以重新实现此事件处理程序以接收此项的鼠标释放事件。 对事件调用QEvent::ignore()QEvent::accept()无效。 默认实现处理基本的项交互,如选择和移动。如果您想在重新实现此函数时保留基本实现,请在重新实现中调用QGraphicsItem::mouseReleaseEvent()。 请注意,mousePressEvent()决定接收鼠标事件的图形项。有关详细信息,请参阅mousePressEvent()描述。

mouseDoubleClickEventmouseMoveEvent也都是一样的描述

相关推荐
2401_841495644 小时前
【操作系统】进程同步与互斥实验报告
c++·算法·操作系统·进程·并发·同步·互斥
fqbqrr4 小时前
2607C++,soui与安卓
c++·soui
fqbqrr7 小时前
2607C++,使用微软detours勾挂工具
c++
mabing99310 小时前
Qt 生成条纹图
开发语言·qt
蓝悦无人机10 小时前
C++基础 — 函数总结
开发语言·c++
Fu_Lin_11 小时前
Qt 嵌入式从零基础到精通总纲
开发语言·qt·嵌入式·qt嵌入式
我不是懒洋洋12 小时前
从零实现一个分布式监控:Prometheus的核心设计
c++
An_s12 小时前
c++对接pdfium(一)win系统篇
开发语言·c++
众少成多积小致巨12 小时前
C++ 规范参考(上)
c++
茯苓gao12 小时前
嵌入式开发笔记:Qt信号槽机制深度解析——从原理到实战的全方位指南
开发语言·笔记·嵌入式硬件·qt·学习