如何在 Qt 层次结构的根小部件中获取鼠标按下事件

Posted

技术标签:

【中文标题】如何在 Qt 层次结构的根小部件中获取鼠标按下事件【英文标题】:How to get mouse pressed events in the root widget of a hierarchy in Qt 【发布时间】:2011-11-16 20:58:33 【问题描述】:

我在使用 Qt 时遇到以下问题(本网站上没有答案似乎完全解决了这个问题,所以我创建了自己的问题)。

我有一个继承自 QWidget 的 MainWindow 类的应用程序。在某个时刻,主窗口内有一个表格,我想捕获所有鼠标按下的事件在该表格之外

我的第一个解决方案是重新实现该方法

/* virtual */ void MainWindow::mousePressEvent(QMouseEvent *event)

在这个方法中,我检查事件的位置,并检查它是否不在表格的 QRect 内。不幸的是,我意识到并不总是调用 mousePressEvent()。我怀疑如果我单击 MainWindow 的另一个子小部件,该小部件会消耗该事件并且不会将其传递给父级。

所以我唯一的替代想法是重新实现 mousePressEvent() 方法为所有 MainWindow 中包含的小部件。这当然不可行,因为:

    其中有很多:如果必须更改在 MainWindow 中实例化的所有小部件类,这将非常复杂、耗时、容易出错且难以维护。 一些子小部件是在并行项目中开发的一些库模块中实现的,所以我无法更改这些。 在其他情况下,子小部件直接使用 Qt 类。 即使我为 2 和 3 定义了自定义子类,我也必须确保在任何地方都使用这些子类而不是原始类。这可能意味着再次回到案例 2。

所以这个替代解决方案对我来说似乎不可行。

总结:您知道是否有一种简单的方法可以从 MainWindow 类中捕获主窗口上的所有鼠标点击

【问题讨论】:

【参考方案1】:

您可以通过在主窗口中安装事件过滤器来做到这一点。查看 Qt 文档中的 QObject::installEventFilter()。

【讨论】:

感谢您的提示。我已经实现了一个过滤器,在我看来过滤器有同样的问题:没有发送到主窗口的事件也没有发送到过滤器。我必须做更多的测试。当我找到解决方案时,我会发布。 如果没有其他方法,请在 QApplication 对象上安装事件过滤器。所有事件都将通过该过滤器。 +1:在 QApplication 上安装事件过滤器可以工作并且实现起来非常简单。此外,我必须使用 globalPos() 方法从事件中获取位置。【参考方案2】:

您可以将属性Qt::WA_TransparentForMouseEventsQWidget::setAttribute 设置为除表格外的所有子小部件,以获取MainWindow 中的鼠标事件(仅当表格是MainWindow 的直接子级时才有效) .

或者做相反的事情,在整个MainWindow 上方添加一个透明小部件,在桌子的位置有一个洞。当您希望它让点击通过或捕捉它们时,您设置/取消设置该小部件的Qt::WA_TransparentForMouseEvents。 可以使用QWidget::setMask()QRegion::substracted() 创建孔。

【讨论】:

以上是关于如何在 Qt 层次结构的根小部件中获取鼠标按下事件的主要内容,如果未能解决你的问题,请参考以下文章

Qt 的鼠标事件

获取 Qt 小部件以更新使用 Qt Designer 制作的 Qt 表单中的鼠标事件

如何避免鼠标单击一个小部件触发 Qt 中其他小部件的信号?

QT的ouseMoveEvent

QWidget 在鼠标按下事件后没有响应。

如何通过拖动鼠标 QT 检查按钮?鼠标移动事件