我正在尝试创建一个PYQT5应用程序,在其中我使用了某些标签来显示状态变量。为了更新它们,我已经手动实施了自定义pyqtSignal
。但是,在调试时,我发现GUI QLabel
的值已更改,但值不会在主窗口上反映。
偶尔会打电话给QApplication().processEvents()
的一些答案。但是,这立即使应用程序崩溃并冻结了应用程序。
这是示例代码(所有必需的库已导入,这只是创建问题的部分,实际代码很大):
from multiprocessing import Process
def sub(signal):
i = 0
while (True):
if (i % 5 == 0):
signal.update(i)
class CustomSignal(QObject):
signal = pyqtSignal(int)
def update(value):
self.signal.emit(value)
class MainApp(QWidget):
def __init__(self):
super().__init__()
self.label = QLabel("0");
self.customSignal = CustomSignal()
self.subp = Process(target=sub, args=(customSignal,))
self.subp.start()
self.customSignal.signal.connect(self.updateValue)
def updateValue(self, value):
print("old value", self.label.text())
self.label.setText(str(value))
print("new value", self.label.text())
print
语句的输出符合预期。但是,标签中的文本不会更改。
CustomSignal
中的update
功能由某些线程调用。我应用了相同的方法来更新进度条,该方法正常。
除了processEvents()
?
OS是Ubuntu 16.04。
关键问题在于代码背后的概念。
流程具有其自己的地址空间,并且除非使用某些过程间通信算法,否则请勿与其他过程共享数据。也许,使用multithreading
模块代替threading
模块来带来并发,以避免Python的GIL和加速程序。但是,子过程无法访问父进程的数据。
我已经测试了这种情况的两种解决方案,它们似乎有效。
-
螺纹模块:无论python中的线程效率低下,因此在某种程度上仍然足以满足基本的并发需求。注意并发和加速之间的区别。
-
qthread :由于您使用的是PYQT,因此使用QThread没有任何问题,这是一个更好的选择,而不是在中间python。
尝试添加
self.label.repaint()
更新文本后,立即:
self.label.setText(str(value))
self.label.repaint()