如何在不同操作系统上处理 Qt 中的不同事件序列?

Posted

技术标签:

【中文标题】如何在不同操作系统上处理 Qt 中的不同事件序列?【英文标题】:How to handle different event sequence in Qt on different operation systems? 【发布时间】:2015-04-03 21:00:07 【问题描述】:

我有跨平台的 Qt 应用程序,它具有从 QGraphicsScene 和基于 QGraphicsItem 的元素继承的自定义图形场景。 我的场景和自定义项目都有上下文菜单,所以我在我的类中重载了 contextMenuEvent() 方法。我也超载了所有其他人 鼠标事件处理程序(mousePressEvent()mouseReleaseEvent()mouseDoubleClickEvent() 等)。我想有同样的行为 我在不同操作系统上的应用程序。在 Windows 上 contextMenuEvent() 处理程序在 mouseReleaseEvent() 处理程序之后调用, 但在 unix 系统上,首先调用 mouseReleaseEvent() 处理程序,并且仅在该 contextMenuEvent() 处理程序之后调用。当我表现正确时 鼠标按钮单击项目的场景上下文菜单上的项目并调用 MyGraphicsScene::focusOutEvent()。 所以 Windows 上的事件处理程序序列是:

MyGraphicsScene::mousePressEvent()
MyGraphicsItem::mousePressEvent()
MyGraphicsScene::mouseReleaseEvent()
MyGraphicsItem::mouseReleaseEvent()
MyGraphicsScene::contextMenuEvent()
MyGraphicsItem::contextMenuEvent()
MyGraphicsScene::focusOutEvent()

Linux 上的事件处理程序序列为:

MyGraphicsScene::mousePressEvent()
MyGraphicsItem::mousePressEvent()
MyGraphicsScene::contextMenuEvent()
MyGraphicsItem::contextMenuEvent()
MyGraphicsScene::focusOutEvent()

并且 mouseReleaseEvent() 处理程序未被调用。

我在 mouseReleaseEvent() 方法中执行了非常重要的操作,并且必须在 Linux 上进行一些解决方法或执行其他操作才能获得正确的行为。 由于 Qt 文档状态 mouseReleaseEvent() 处理程序清除场景的鼠标抓取器项目,因此我了解丢失 mouseReleaseEvent() 调用 导致之前的鼠标抓取器项目保持不变并且仍然可以从场景中获取所有事件的情况。

为了在 Linux 上完全清楚,当我用鼠标右键调用项目上下文菜单时,我的应用程序中出现了这种情况,单击菜单执行 对项目进行一些操作(例如旋转它),然后当我想移动项目时,它第一次无法移动 - 我必须点击场景,然后才能移动项目。在 Windows 上没有这样的问题,因为菜单项显示在 contextMenuEvent() 处理程序,在 mouseReleaseEvent() 之后调用。

我在我的应用程序中使用 Qt 4.6 版本。

以前有人处理过这样的问题吗?如何在 Linux 上像在 Windows 上一样进行正确的事件处理?

【问题讨论】:

【参考方案1】:

您可以使用预处理器。你的编译器应该有一些预定义的宏来识别你的代码是为哪个操作系统编译的。

#ifdef __linux__
// Linux event loop
#endif
#ifdef _WIN32
// Windows event loop
#endif

【讨论】:

但这不会改变 Linux 和 Windows 上 contextMenuEvent() 和 mouseReleaseEvent() 调用顺序之间的区别。我不相信以前没有人发现过这样的问题。

以上是关于如何在不同操作系统上处理 Qt 中的不同事件序列?的主要内容,如果未能解决你的问题,请参考以下文章

如何对项目的复选框和文本以不同的方式处理点击事件? (PyQt/PySide/Qt)

第38课 Qt中的事件处理(上)

Qt 的事件

当很清楚并且不同的uiview可以处理它们时,如何忽略最上面的uiview中的触摸事件

QT:事件处理过程

第三十八课Qt中的事件处理(上)