【问题标题】:PyQT equivalent of wx CallAfter?PyQT 相当于 wx CallAfter?
【发布时间】:2025-11-30 16:50:01
【问题描述】:

我最近从 wxPython 切换到 PyQT,但找不到 CallAfter 的等价物。由于某些导入,我需要使用 pubsub 并且使用 wx 我刚刚使用 CallAfter 发送消息——有没有办法在 PyQT 中做类似的事情?基本上,我想用 pyQT 在主循环中注入一些东西。

编辑以获取更多信息:

在我使用 wxPython 的旧 GUI 中,我使用的是使用旧调度程序模块的 python-openzwave。我会捕获旧的调度程序信号并将它们转换为 pubsub 消息(为了便于使用)并使用 CallAfter 发送新消息,如下所示:

wx.CallAfter(pub.sendMessage, messagePack.signal, message = messagePack.message)

然后我能够通过捕获消息并直接处理 gui 元素来更新 GUI,因为它本质上是在主循环中注入了一些东西。

现在,使用 pyqt,没​​有 callafter,所以,我有相同的系统设置,没有 callafter,但是在收到消息后必须发生的动作不能发生,因为它在 mainloop 的中间。

【问题讨论】:

  • 您能否详细说明为什么需要这样做(您是否使用线程?如果使用线程是为了什么?如果不是,您在做什么?)?有几种解决方案,正确的解决方案取决于您在做什么。
  • 信号和槽在 Qt 中是自动线程安全的,所以没有真正的等价物(即不需要一个)。
  • 例如,python-openzwave 使用 pubsub 系统来发送有关传感器等的更新。当传感器更新时,我需要它能够更新 GUI。我猜一个转换器函数订阅消息并在 pyqt 发出时重新发送它们可以解决问题吗?这似乎是我不应该需要的一步。
  • @linus72982。 “pubsub”的东西真的让这个问题感到困惑。您能否提供一个更简单的示例来演示您无法解决的一些特定问题?也就是说,类似于CallAfter 的 wx wiki 示例。
  • @linus72982。恐怕我看不出问题出在哪里。定义一个自定义信号,并将其连接到 gui 中的插槽;然后在适当的时候简单地发出带有消息的信号。

标签: python user-interface pyqt pyqt4 publish-subscribe


【解决方案1】:

我能想到的最接近的事情是使用带有短暂超时的QTimer.singleShot,这将迫使它进入下一个事件循环。

def other_function(self):
    print 'other'

def my_function(self):
    print 'one'
    QTimer.singleShot(1, self.other_function)
    print 'two'

Qt 有一个事件循环的概念,它会检查是否有需要处理的事件,比如按钮单击,或者部件的一部分是否需要重绘等。通常,函数被调用作为结果的一个事件。 QTimer.singleShot 将把你的函数调用放在事件循环的下一个周期要处理的事情列表的末尾。

但我同意一些 cmets,您可能可以只使用在另一个线程中运行的单独 QObject 来处理 openzwave 事件并将消息重新调度为 Qt 信号,主线程可以侦听和更新 GUI .

【讨论】:

  • singleShot 可能有效,但我决定回到 wxPy。仅制作一个 QObject 并将信号作为发射器发送的问题是:1)我完全切换到发射器,这有一个问题,即所有其他消息,一些与 gui 零相关的消息,现在都通过 QObjects 处理。 2)我发布一些消息并发出其他消息——这需要发送者知道接收者,但是,格式不好。 3)我将所有消息复制为 pubsubs 并发出。或者我可以在类似的 wx 中使用花哨的 CallAfter。最后一个选项听起来最理智。
  • 而且,老实说,我非常喜欢 wx 提供的更广泛的文档和支持。我喜欢 qt 在开发上看起来更流畅一些,但是 wx 的信息太多了。
  • QObjects 不依赖于 GUI,可以将 QObjects 和 Signals 用于非 GUI 的东西。我不明白下一部分。为什么发送者需要知道接收者?为什么它是不好的形式?什么是发布订阅?有趣的是,我总是发现 Qt 文档示例比 wx 更全面,但 Qt 在我的行业中是一种标准,因此可能与它有关。
  • 我想我可以将信号用于非 gui,我只是更喜欢 pubsub 模块,因为我可以捕获消息类别。例如,我可以拥有 SENSOR.FRONTDOOR.OPEN 并通过订阅“SENSOR”或使用“SENSOR.FRONTDOOR”的所有前门操作来获取它。发送者必须知道接收者,因为在我提到的那个选项中,我必须发送一些消息作为 qt 信号和一些作为 pubsub 消息,所以发送者必须知道它的去向。这是一种糟糕的形式,因为它是紧密耦合的。 PyPubSub 是一个允许来回发送消息的模块。它在 PyPi 中。
  • 我不认为你使用 Qt Signals 是正确的。发送者永远不必知道接收者的任何信息。发送者发出信号,接收者订阅它们。我不知道 Qt 中有什么会执行诸如 SIGNAL.SUBSIGNAL.SUBSIGNAL 之类的嵌套事件,这听起来很酷,但我确信添加这种类型的语法糖并不难。我认为在 Qt 中更简单的方法是在信号中包含该信息,然后让接收器过滤掉它不关心的信息。
最近更新 更多