0

我正在尝试创建一个 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语句的输出符合预期。但是,标签中的文本不会改变。

in 中的update函数CustomSignal被某个线程调用。我已经应用了相同的方法来更新进度条,效果很好。

除此以外,还有其他解决方法processEvents()吗?

操作系统是 Ubuntu 16.04。

4

2 回答 2

0

尝试添加

self.label.repaint()

更新文本后立即,如下所示:

self.label.setText(str(value))
self.label.repaint()
于 2020-11-03T17:56:12.037 回答
0

关键问题在于代码背后的概念。

进程有自己的地址空间,不会与其他进程共享数据,除非使用了某种进程间通信算法。或许,multithreading使用模块代替threading模块来带来并发以避免Python的GIL并加速程序。但是,子进程无法访问父进程的数据。

我已经针对这种情况测试了两种解决方案,它们似乎有效。

  • threading 模块:尽管 Python 中的线程由于 GIL 而效率低下,但在一定程度上仍然足以满足基本的并发需求。注意并发和加速之间的区别。

  • QThread:由于您使用的是 PyQt,因此使用 QThread 没有任何问题,这是一个更好的选择,因为它利用操作系统的系统调用而不是中间的 Python 来实现多个内核的并发性。

于 2016-12-27T16:34:41.300 回答