我编写了这个示例代码,试图找出如何在后台线程和主线程之间进行通信。据我了解,一个线程不能简单地与UI或不同线程中存在的变量进行交互。
我想抓住列表'数据'在后台线程中,然后将其显示在< lbl2'在UI中。如果该程序按原样运行,它将在命令行上打印我想要的结果。
Data received in background thread = [1, 2, 3, 4, 5]
Q1:从后台线程到主线程发送数据(如列表或字符串)的正确方法是什么?
Q2:我将如何开始在示例代码中实现它?
#!/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_())
答案 0 :(得分: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)