2016-12-25 123 views
0

我正在嘗試創建一個PyQt5應用程序,其中我使用了某些標籤來顯示狀態變量。要更新它們,我已手動實施自定義pyqtSignal。但是,在調試時,我發現GU​​I QLabel的值已更改,但這些值未反映在主窗口上。爲什麼有些小部件不會在Qt5上更新?

有些答案建議偶爾撥打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()

操作系統是Ubuntu 16.04。

+0

顯示您的代碼以幫助您 – eyllanesc

+0

添加示例代碼。 –

+0

請發佈一個完整的代碼(或至少一個完整代碼的精簡版),否則我們很難複製這個問題,只是看代碼的一部分並幫助你。 – Eddie

回答

0

關鍵問題在於代碼背後的概念。

進程擁有自己的地址空間,除非使用某些進程間通信算法,否則不會與其他進程共享數據。也許,multithreading模塊被用來代替threading模塊來帶來併發性,以避免Python的GIL並加速程序。但是,子進程無法訪問父進程的數據。

我已經測試了兩種解決方案,這種情況下,他們似乎工作。

  • 線程模塊:無論線程在Python是由於GIL效率不高,但它仍然足以在一定程度上爲基本的併發性的要求。請注意併發和加速之間的區別。

  • 的QThread:由於您使用PyQt的,有沒有在使用的QThread,這是一個更好的選擇,因爲它需要併發到多核利用操作系統的系統調用的任何問題,而不是Python中的中間。

相關問題