2015-11-08 34 views
1

我已經寫了這個示例代碼來試圖弄清楚如何在後臺線程和主線程之間進行通信。據我所知,一個線程不能簡單地與不同線程中存在的UI或變量交互。如何從QThread線程發送列表對象到UI的主線程?

我想在後臺線程中獲取'data'列表,然後在UI中顯示'lbl2'。如果這個程序按原樣運行,它將在命令行上打印我想要的結果。

Data received in background thread = [1, 2, 3, 4, 5] 

Q1:什麼是如列表或字符串數​​據,從後臺線程發送到主線程的正確方法是什麼?

問題2:如何在示例代碼中實現該功能?

#!/usr/bin/env python3.4 
from PySide.QtGui import QPushButton, QApplication, QWidget, QLabel 
from PySide.QtCore import QThread, QCoreApplication 
import queue 
import sys 


class Gui(QWidget): 
    def __init__(self): 
     super(Gui, self).__init__() 
     self.initUI() 

    def initUI(self): 
     lbl1 = QLabel('Data Recieved =', self) 
     lbl2 = QLabel('None', self) 
     lbl2.move(85, 0) 
     lbl2.resize(100, 15) 
     qbtn = QPushButton('Quit', self) 
     qbtn.clicked.connect(QCoreApplication.instance().quit) 
     qbtn.move(0, 20) 
     btn = QPushButton('Get Summary', self) 
     btn.move(100, 20) 
     btn.clicked.connect(lambda: bgThread.summary()) 
     self.setGeometry(300, 300, 200, 50) 
     self.setWindowTitle('Thread Communication Example') 
     self.show() 


class BackgroundThread(QThread): 
    def __init__(self, q, loop_time=1.0/60): 
     self.q = q 
     self.timeout = loop_time 
     super(BackgroundThread, self).__init__() 

    def onThread(self, function, *args, **kwargs): 
     self.q.put((function, args, kwargs)) 

    def run(self): 
     while True: 
      try: 
       function, args, kwargs =  self.q.get(timeout=self.timeout) 
       function(*args, **kwargs) 
      except queue.Empty: 
       self.idle() 

    def idle(self): 
     pass 

    def _summary(self): 
     # Run function which will return a list object 
     # data = externalclass.summary() 
     # Need to send list:'data' to the main thread. 
     data = [1, 2, 3, 4, 5] 
     print('Data received in background thread =', data) 

    def summary(self): 
     self.onThread(self._summary) 


if __name__ == "__main__": 
    app = QApplication(sys.argv) 
    # Setup background thread 
    request_queue = queue.Queue() 
    bgThread = BackgroundThread(request_queue) 
    bgThread.start() 
    # Setup Gui 
    ui = Gui() 
    sys.exit(app.exec_()) 

回答

2

您可以自定義一個信號,它可以在線程間安全地發出:

from PySide.QtCore import Signal 

class Gui(QWidget): 
    def initUI(self): 
     ... 
     bgThread.dataReceived.connect(lambda data: lbl2.setText(str(data))) 

class BackgroundThread(QThread): 
    dataReceived = Signal(list) 
    ... 

    def _summary(self): 
     ... 
     self.dataReceived.emit(data) 
+0

這完美地工作,謝謝!雖然,對於測試程序,我不得不添加'lbl2.resize(100,15)',以便標籤正確顯示。 –

相關問題