如何将列表对象从QThread线程发送到UI的主线程? [英] How can I send a list object from a QThread thread to the UI's main thread?

查看:165
本文介绍了如何将列表对象从QThread线程发送到UI的主线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经编写了此示例代码,以尝试弄清楚如何在后台线程和主线程之间进行通信.据我了解,线程不能简单地与UI或其他线程中存在的变量进行交互.

I have written this example code to try and figure out how to communicate between a background thread, and the main thread. As I understand it, a thread cannot simply interact with the UI or variables existing in a different thread.

我想在后台线程中获取列表数据",然后将其显示在用户界面的"lbl2"上.如果此程序按原样运行,它将在命令行上打印我想要的结果.

I would like to grab the list 'data' in the background thread, then display it on 'lbl2' in the UI. If this program is run as is, it will print the result I want on the command line.

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

问题1:从后台线程向主线程发送诸如列表或字符串之类的数据的正确方法是什么?

问题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_())

推荐答案

您可以定义一个自定义信号,该信号可以安全地跨线程发出:

You can define a custom signal, which can be safely emitted across threads:

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)

这篇关于如何将列表对象从QThread线程发送到UI的主线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆