Qt 如何将MousePresseEvent()传播到一组QGraphics站点?

Qt 如何将MousePresseEvent()传播到一组QGraphics站点?,qt,mouseevent,qgraphicsitem,Qt,Mouseevent,Qgraphicsitem,我正在编写一个使用Qt图形视图框架的程序。我将QGraphicsItem子类化为一个包含其他QGraphicsItem(或其其他子类)的类。此类是包含的QGraphicsItem的父类;其思想是使用复合对象 从表面上看,我试图实现的目标似乎存在冲突: 在mousePressEvent中调用ignore(),将使我的对象不可移动。我想把它搬走 在mousePressEvent中调用accept(),将阻止事件传播到子对象。一些子对象应该对鼠标事件作出反应 我怎样才能做到这一点呢?我认为您对文档

我正在编写一个使用Qt图形视图框架的程序。我将
QGraphicsItem
子类化为一个包含其他
QGraphicsItem
(或其其他子类)的类。此类是包含的
QGraphicsItem
的父类;其思想是使用复合对象

从表面上看,我试图实现的目标似乎存在冲突:

  • mousePressEvent
    中调用
    ignore()
    ,将使我的对象不可移动。我想把它搬走
  • mousePressEvent
    中调用
    accept()
    ,将阻止事件传播到子对象。一些子对象应该对鼠标事件作出反应

我怎样才能做到这一点呢?

我认为您对文档的解释是不正确的

mousePressEvent
中调用
ignore()
,将使我的对象不可移动

我不相信那是真的。在我看来,调用
ignore()
就像一个对象说“我已经评估了这个事件。我已经采取了所有我想要的行动来响应这个事件。我还决定它不是为我准备的,所以我现在将它传递给我下面的下一个对象”。我找不到任何提示ignore事件将取消设置
QGraphicsItem::ItemIsMovable
标志(这是决定QGraphicsItem是否可移动的因素)

我不明白为什么您不能让对象移动
忽略事件()
,但我建议这不是一种明智的方法(在大多数情况下:显然您可能有理由这样做)

mousePressEvent
中调用
accept()
,将阻止事件传播到子对象


我相信这是真的,但家长仍然可以修改自己的孩子。我的理解是调用
accept()
就像一个对象说“我已经评估了这个事件。我已经采取了所有我想要的行动来响应这个事件(可能包括修改我的孩子)。我还决定这个事件是为我准备的,所以我不会将事件传递给你的父母QGraphicsItem。”,你可以试试看

MyObject::mousePressEvent ( QGraphicsSceneMouseEvent * event )
{
    QGraphicsItem::mousePressEvent(event);
    event->ignore();
}
这将允许正常处理鼠标事件(即,使对象可移动),但随后将忽略它以使其传播


不过,这种逻辑需要更加稳健,因为如果父级和子级响应同一个鼠标事件,则副作用的风险很高。

Send
QCoreApplication::postEvent(child,mouseEvent)
到子对象。

您是否考虑过通过让父处理程序调用QApplication::postEvent将事件发送到项目的每个子对象上?忽略我的最后一条注释。坏主意。请参见下面Styne的回答。我现在正在尝试:鼠标左键按下是移动动作的开始,因此它在
mousePressEvent()
中被接受,并由对象处理。没有其他对象将获取该事件。对于其他输入(右键、修改器键),事件将被忽略并移动到下一个对象。Stynes666说得对,有一些东西没有太大意义。移动的问题是由于缺少鼠标移动事件造成的:“如果调用QEvent::ignore()在事件发生时,此项目将丢失鼠标抓取,并且事件将传播到下面的任何最上面的项目。除非收到新的鼠标按下事件,否则不会向此项目发送更多的鼠标事件。”因此(假设您有充分的理由响应事件并表示忽略它)在调用ignore之前执行您的响应。按照建议在通知孩子们之后调用accept()(获取mouseMoveEvents)更有意义。实际上,我通过调用childrens的mousePresseEvent()方法尝试了这一点,但因为它们是受保护的成员。我肯定我能找到解决办法,但它看起来很难看。我问这个问题的主要动机是想得到一个更好的建议。我已经尝试过了,但问题是在调用
ignore()
之后,对象不会收到更多的鼠标事件。这就是前进的方向。