【问题标题】:wx's idle and UI update events in PyQtPyQt 中 wx 的空闲和 UI 更新事件
【发布时间】:2010-10-12 01:31:03
【问题描述】:

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”的方式是什么?

【问题讨论】:

    标签: python qt wxpython pyqt


    【解决方案1】:

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

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

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

    你必须多说一点你在做什么来解释为什么你需要一个与 Qt 中的这个事件等效的事件。

    【讨论】:

    • 谢谢。我已经举了一个例子,很想听听意见
    • 实现应用程序的一种方法是为每个状态设置一个槽,在该槽中以您描述的方式更新小部件。因此,例如,您可能有一个插槽,您可以在其中更新状态栏并禁用开始按钮。每个插槽都会启动一些会导致下一个插槽的任务。
    • 您可能会发现 Qt 的 FTP 和 Find Files 示例很有用。
    【解决方案2】:

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

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

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 是的,但是 EVT_IDLE 只发送一次。我怎样才能制作这样一个计时器,当没有其他事件时只发送一次?我不认为我可以(单发在这里没有帮助,因为我想要这个每次没有其他事件)
      【解决方案4】:

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

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

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

      【讨论】:

        猜你喜欢
        • 2017-04-17
        • 1970-01-01
        • 1970-01-01
        • 2012-11-13
        • 1970-01-01
        • 1970-01-01
        • 2013-02-15
        • 2013-09-13
        • 1970-01-01
        相关资源
        最近更新 更多