我在从QPushButton派生的对象中有一个方法,它应该在通过QtDBus从子进程接收状态更新时更改按钮的背景颜色。
def setStatus( self, test, status, init=False ):
"""
Update status for specified test.
Parameters:
-----------
test: str
String ID of test to set status for.
status: str
String ID of new status.
init: bool
Whether status map is being initialized.
"""
sts = self.status_dict[ status ] # validate status
if init or self._status[ test ] != sts.name: # check that it's actually changed
self._status[ test ] = sts.name
if test == current_test: # Update UI only if test matches current view
self.setStyleSheet( "background-color:{};".format( sts.color ) )
self.setText( "{}: {}".format( self._NAME, sts.desc ) )
self.update()
self.status_changed.emit()
我知道它进入if test==current_test
循环,并成功返回。
此外,我覆盖了paintEvent方法,以便在此窗口小部件上发生绘制事件时打印消息。但是,对update()的调用永远不会触发绘制事件。用self.paint()
替换它也没有效果。
此方法也是从对象的构造函数中调用的,它按预期工作。此外,如果我将其设置为每次单击按钮时都被调用它也可以。
是否存在忽略更新和重绘的条件。我在Qt文档中找不到任何内容。
我确定通过DBus发送消息的子进程也接收它。因此,消息永远不会进入QT GUI事件循环正在运行的主进程。这就是为什么用户界面没有更新的原因。
在创建和注册QDBusAbstractAdapter实例后生成子流程,因此副本存在于与QDBusAbtractInterface相同的子流程中。因此,接口在同一进程中向适配器发送消息。
子进程运行龙卷风IOLoop,监听ZMQStreams,而不是Qt事件循环。所以我不知道是什么触发了QtDBus适配器插槽。
我可以想到发生了什么的几种可能性:
Qt事件循环使用下面的Tornado IOLoop,因此在生成子进程时,QtDBus适配器已经注册了tornado。
当Qt事件循环在主进程中启动时,它也会以某种方式在子进程中启动。
调用QtDBus接口上的QtDBus适配器插槽会启动一个临时的Qt事件循环。
无论如何,在不知道幕后发生了什么的情况下,我认为最好的解决方案是在创建QApplication之前启动子流程。然后,一旦必要的信息可用于初始化它们,让他们监听来自主进程的信号以启动其主要事件循环。