2

wx(和 wxPython)在 PyQt 中有两个我想念的事件:

  • EVT_IDLE被发送到一个框架。它可用于根据应用程序的状态更新各种小部件
  • EVT_UPDATE_UI当它必须重新绘制和更新时被发送到一个小部件,所以我可以在处理程序中计算它的状态

现在,PyQt 似乎没有这些,PyQt 书建议编写一个updateUi方法并手动调用它。我什至最终每 0.1 秒从计时器调用一次,以避免从可能更新 GUI 的方法中进行许多手动调用。我错过了什么吗?有没有更好的方法来实现这一目标?


一个例子:我有一个简单的应用程序,带有一个启动按钮,可以启动一些处理。仅当使用菜单打开文件时才应启用开始按钮。此外,状态栏上还有一个显示信息的永久小部件。

我的应用程序有状态:

  1. 打开文件之前(在这种状态下,状态栏显示一些特殊的东西并且开始按钮被禁用)
  2. 文件已打开且未开始处理:启动按钮已启用,状态栏显示其他内容
  3. 处理正在运行:开始按钮现在显示“停止”,状态栏报告进度

在 Wx 中,我会让按钮的更新 UI 事件处理其状态:其上的文本,以及它是否已启用,具体取决于应用程序状态。状态栏也是如此(或者我会使用 EVT_IDLE)。

在 Qt 中,我必须在几个可能影响状态的方法中更新按钮,或者只是创建一个 update_ui 方法并在计时器中定期调用它。什么是更“QT”的方式?

4

4 回答 4

5

在 wxWidgets 中使用 EVT_UPDATE_UI 似乎突出了 wxWidgets 和 Qt 期望开发人员在其代码中处理事件的方式的根本区别之一。

使用 Qt,您可以在用户界面中的小部件之间连接信号和插槽,或者在每个插槽中处理“业务逻辑”,或者将其委托给专用方法。您通常不必担心对 GUI 中的每个小部件进行单独更改,因为任何重绘请求都将放置在事件队列中,并在控制返回事件循环时交付。为了效率,一些绘制事件甚至可以合并在一起。

因此,在使用信号和槽来处理状态更改的普通 Qt 应用程序中,基本上不需要有空闲机制来监视应用程序的状态并更新小部件,因为这些更新应该自动发生。

您将不得不多说一些关于您正在做什么来解释为什么您需要在 Qt 中与此事件等效的事件。

于 2009-03-09T01:40:31.297 回答
2

我会发送 Qt 信号来指示状态变化(例如 fileOpened、processingStarted、processingDone)。管理开始按钮和状态栏小部件(或子类)的对象中的插槽可以连接到这些信号,而不是“轮询”空闲事件中的当前状态。

如果您希望信号在事件循环中稍后而不是立即延迟(例如,因为它会花费一些时间来做某事),您可以使用“排队”信号槽连接而不是正常类型。

http://doc.trolltech.com/4.5/signalsandslots.html#signals

连接类型是 connect() 函数的可选参数: http://doc.trolltech.com/4.5/qobject.html#connecthttp://doc.trolltech.com/4.5/qt.html#ConnectionType-枚举

于 2009-03-09T14:06:54.310 回答
1

据我了解,EVT_IDLE 在应用程序消息队列为空时发送。Qt 中没有这样的事件,但是如果你需要在没有未决事件的情况下在 Qt 中执行某些事情,你应该使用 0 超时的 QTimer。

于 2009-03-08T21:04:37.683 回答
1

一般来说,更 Qt 的方式是在任何需要更新的功能中根据需要更新按钮/工具栏,或者整合一些功能并在程序需要时直接调用该功能(例如 updateUi 功能)。

您应该知道,在 Qt 中,更改 Ui 元素的属性不会导致立即重绘,但会在事件系统中对重绘进行排队,并且在可能的情况下将多个重绘调用压缩为一个。

至于与状态相关的多项更改,请查看这篇博客文章,了解即将推出的 Qt 新增功能,以便更轻松地处理状态。看起来这会解决你的很多抱怨,因为在你的多个函数中,你可以只转换状态变量,并且 UI 的其他部分应该更新以匹配。这并不肯定它会进入下一个 Qt 版本(尽管我会打赌,或者类似的东西),而且我不知道 PyQt 与 Qt 版本的跟踪有多密切。或者,您可以使用该概念并创建自己的类来根据需要跟踪状态。

于 2009-03-09T18:31:03.723 回答