如何让 QThreads 在控制台 PySide 程序中工作? [英] How to get QThreads to work in a console PySide program?

查看:51
本文介绍了如何让 QThreads 在控制台 PySide 程序中工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试学习如何在 Python 程序中使用线程.我正在使用 PySide 和 QThreads,因为之后我将使用 PySide 实现 gui.

I'm trying to learn how to use threading in a python program. I'm using PySide and QThreads since I'm going to implement gui afterwards with PySide.

我已经理解了线程的主要概念,至少我认为是这样.但我仍然对事件循环感到困惑.我认为这就是我的应用程序的问题.

I have understood the main consept of threading, at least I think. But I'm still confused with event loops. And I think that is the problem with my aplication.

这是我无法正常工作的示例应用程序.在我的主类中,我有几个工作线程,我希望他们向主类报告他们的进度.但是主程序不会实时打印进度信息.

Here is a sample application that I can't get to work properly. In my main class I have several worker threads and I want to them to report their progress to the main main class. But the main program don't print progress messages in real time.

我怎样才能让它发挥作用?

How could I get this to work?

from PySide import QtCore
import time, sys

class MyWorkerThread(QtCore.QThread):
    message = QtCore.Signal(str)

    def __init__(self, id, parent=None):
        super(MyWorkerThread, self).__init__(parent)
        self.id = id

    def run(self):
        for i in range(10):
            self.message.emit("%d: %d" % (self.id, i))
            time.sleep(0.2)

class MainProgram():
    def __init__(self, parent=None):
        self.threads = []

        self.addWorker(MyWorkerThread(1))
        self.addWorker(MyWorkerThread(2))

    def addWorker(self, worker):
        worker.message.connect(self.printMessage, QtCore.Qt.QueuedConnection)
        self.threads.append(worker)

    def startWorkers(self):
        for worker in self.threads:
            worker.start()
            worker.wait()
        self.workersFinished()

    def workersFinished(self):
        QtCore.QCoreApplication.instance().quit()

    @QtCore.Slot(str)
    def printMessage(self, text):
        sys.stdout.write(text+'\n')
        sys.stdout.flush()

if __name__ == '__main__':
    app = QtCore.QCoreApplication(sys.argv)
    m = MainProgram()
    m.startWorkers()
    sys.exit(app.exec_())

推荐答案

worker.wait() 是问题所在.此调用会阻塞主线程(在本例中为一个正在运行的事件循环),直到工作线程完成其工作.

worker.wait() is the problem. This call blocks the main thread (in this case the one running event loop) until the worker finishes its job.

这是一个略有变化的版本(我已经评论了我的更改):

Here is a slightly changed version (I've commented my changes):

from PySide import QtCore
import time, sys

class MyWorkerThread(QtCore.QThread):
    message = QtCore.Signal(str)

    def __init__(self, id, parent=None):
        super(MyWorkerThread, self).__init__(parent)
        self.id = id

    def run(self):
        for i in range(10):
            self.message.emit("%d: %d" % (self.id, i))
            time.sleep(0.2)

class MainProgram():
    def __init__(self, parent=None):
        self.threads = []

        self.addWorker(MyWorkerThread(1))
        self.addWorker(MyWorkerThread(2))

    def addWorker(self, worker):
        worker.message.connect(self.printMessage, QtCore.Qt.QueuedConnection)
        # connect the finished signal to method so that we are notified
        worker.finished.connect(self.workersFinished)
        self.threads.append(worker)

    def startWorkers(self):
        for worker in self.threads:
            worker.start()
            # no wait, no finished. you start the threads and leave.

    def workersFinished(self):
        if all(worker.isFinished() for worker in self.threads):
            # wait until all the threads finished
            QtCore.QCoreApplication.instance().quit()

    @QtCore.Slot(str)
    def printMessage(self, text):
        sys.stdout.write(text+'\n')
        sys.stdout.flush()

if __name__ == '__main__':
    app = QtCore.QCoreApplication(sys.argv)
    m = MainProgram()
    m.startWorkers()
    sys.exit(app.exec_())

这篇关于如何让 QThreads 在控制台 PySide 程序中工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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