C++ Qt——将事件传递给多个对象?

C++ Qt——将事件传递给多个对象?,c++,qt,C++,Qt,我基本上有3个层(Window>Scene>View),每个层都需要处理mouseMove事件,而不阻塞其他层。不过,似乎只有最小的孩子参加了这次活动。我希望我可以处理该事件,然后调用event->ignore()将该事件传递回堆栈,但它似乎不起作用 如果需要,请提供一些相关代码: void EditorWindow::createScene() { m_scene = new EditorScene(this); m_view = new EditorView(m_scene)

我基本上有3个层(
Window>Scene>View
),每个层都需要处理
mouseMove
事件,而不阻塞其他层。不过,似乎只有最小的孩子参加了这次活动。我希望我可以处理该事件,然后调用
event->ignore()
将该事件传递回堆栈,但它似乎不起作用

如果需要,请提供一些相关代码:

void EditorWindow::createScene() {
    m_scene = new EditorScene(this);
    m_view = new EditorView(m_scene);
    // ...
}

void EditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent* mouseEvent) {
    printf("B\n");
    // ...
}

void EditorView::mouseMoveEvent(QMouseEvent* event) {
    printf("C\n");
    event->ignore();
}
只打印“C”。请注意,
EditorScene
EditorView
接收不同类型的鼠标事件,因此传递它们并不完全是件小事

EditorWindow
也需要鼠标坐标;目前,我正在发送一个被窗户抓住的孩子的信号。。。但实际上没有必要用这种方式传递,对吗


找到这个。调用
ignore()。听起来它应该能工作,但也许它意味着一个无关的接收者。传播它的正确方法实际上是调用
BaseClass::Event
,如下所示:

void EditorView::mouseMoveEvent(QMouseEvent* event) {
    QGraphicsView::mouseMoveEvent(event); // propogate to parent widget
    printf("C\n");   
}
现在它正在打印BCBC。。。这是伟大的,但我似乎不能推动它一个更高的水平


另一个编辑:它被正确地传播,我只是没有启用
setMouseTracking

QGraphicsView::mouseMoveEvent(event);
不会向上传播到父对象,而是向下传播到场景

下面是发生的情况——QGraphicsView接收QMouseEvent,将其转换为QGraphicsSceneMouseEvent并将其传递到场景。场景然后将其传递到适当的项目,或者在您的情况下,打印“B”。事件处理程序然后返回EditorView并打印“C”

然后,如果显式忽略事件(默认情况下接受鼠标移动),Qt事件处理程序将把事件传递给EditorView的父级。所以,在打印“C”后尝试忽略

鼠标移动的另一个特点是:

如果关闭鼠标跟踪,则只有在移动鼠标时按下鼠标按钮,才会发生鼠标移动事件。如果打开鼠标跟踪,即使未按下鼠标按钮,也会发生鼠标移动事件

因此,请确保在EditorView的父级上启用了跟踪(或按下按钮:)

编辑: 顺便说一句,EditorScene不是EditorView的父级。好的,它在您的代码中,但仅在父关系的QObject含义中(仅限内存管理)

QGraphicsScene和View没有正常的家庭关系——场景可以有多个视图,这些视图是不相关父视图的子视图

为了进行窗口事件传播,必须具有基于QWidget的父级。事实上,我很确定您将EditorView重新分配到EditorWindow或其子项之一(当您将其添加到布局中时)

INSTAEDIT: 对于希望视图本身发出信号的坐标。出于解耦的原因,也因为您可能希望显示视图的局部坐标,而不是父窗口的坐标,也不是屏幕坐标(对吗?)。若你们真的想要场景坐标,视图也是正确的选择,因为它知道变换矩阵

坐标是这样的:
屏幕->编辑窗口本地->编辑视图本地->场景转换->本地转换的任何项目。

QGraphicsView::MousePresseEvent(e)在我的MousePresseEvent中完成了这个技巧

我认为QGraphicscene默认情况下会打开鼠标跟踪。EditorScene是EditorView的父级。我可以用最后一段代码将事件从EditorView传递到EditorScene;它使EditorWindow的级别更高,这就是问题所在。。。虽然目前不是一个紧迫的问题。EditorWindow是否启用了鼠标跟踪功能?哦,没错。QGraphicsView不需要SetMouseTrack,但主窗口需要。当鼠标悬停在其他小部件的上方时,它仍然不会拾取鼠标移动。基本上,我希望EditorWindow在鼠标悬停在EditorView的上方时抓住鼠标坐标,这样我就可以在状态栏上显示坐标,状态栏是EditorWindow的一个成员。只让场景发送一个信号会更好吗?re:您的编辑:View通过
mapToScene
函数了解场景坐标,但它没有
mouseMoveEvent
提供这些坐标给您。。。我不太相信从现场发送信号是一个可怕的想法,因为即使你切换到另一个视图,它仍然有意义。