gpt4 book ai didi

qt - 何时调用异步 QMenu::popup() 与同步 QMenu::exec()?

转载 作者:行者123 更新时间:2023-12-02 19:19:01 28 4
gpt4 key购买 nike

Reading the Qt5 source code ,我注意到 QLabel::contextMenuEvent() 使用这种(非阻塞)样式:

QMenu *menu = ...
menu->setAttribute(Qt::WA_DeleteOnClose);
// Non-blocking
menu->popup(event->globalPos());

或者,我从 Qt 代码示例中看到了这种(阻塞)样式:

QMenu *menu = ...
// Blocking
QAction* action = menu->exec(event->globalPos());
// Or before menu->exec() call: menu->setAttribute(Qt::WA_DeleteOnClose)
delete menu;

我可以看到这些差异:

  • 非阻塞与阻塞
  • 返回voidQAction*

他们还有其他区别吗?示例:非阻塞是否有优点,例如,事件循环可以处理其他事件?如果差异纯粹是风格,请告诉我。

最后,我确实注意到在 GNU/Linux/KDE 上调试非阻塞风格对我来说有点奇怪,但这可能是无关的。

最佳答案

When to call QMenu::popup() vs QMenu::exec()?

前者:总是。后者:从来没有。就这么简单。

为什么?因为重新进入事件循环会导致意大利面条式代码。世界是异步的,你不能假装你正在“等待”同步代码中的某些内容,而世界仍在继续,并执行这种代码风格向你隐藏的各种事情。 exec() 调用的真正含义是“运行应用程序的任意部分,直到用户决定他们已经受够了弹出窗口的不确定时间”。如果这听起来很糟糕,那么它的意思是:这是开发 UI 代码的令人讨厌的、有缺陷的、糟糕的方式,并且会导致难以调试的错误,并且允许你拖延而不是花时间以异步方式实际完成它。让我感到震惊的是,Qt 项目仍然在其代码示例中提供了这一点。 exec() 是可禁止的。在极少数情况下,由于 Qt 的平台特定代码被破坏而必须使用它。例如。 Qt 没有费心(我上次检查过)从 MacOS 上的主运行循环实现 QDrag 支持,因此他们启动了本地运行循环,只是因为 Apple 的示例代码显示了相同的白痴,而它可以是没有 AFAIK 就完成了(虽然它是 nbot 一样微不足道 - 但那又怎样,它是库代码,它不应该总是微不足道 - 否则用户可以自己做)。

您可以使用状态机 (QStateMachine) 来指定应用程序的行为,为特定弹出窗口可见时提供专用状态,然后您可以作为应用程序执行必要的响应退出该状态。您还可以使用 C++20 协程编写 Qt ui 代码,并使用一些脚手架代码来实现这一点(Qt 尚未提供任何代码)。

关于qt - 何时调用异步 QMenu::popup() 与同步 QMenu::exec()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63303201/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com