GUI中的Python线程

GUI中的Python线程,python,python-3.x,pyqt5,qthread,pyside2,Python,Python 3.x,Pyqt5,Qthread,Pyside2,我正试图让一个长时间运行的方法在一个单独的线程中运行。该功能正在工作,但仍会导致GUI在方法运行时冻结。我是否遗漏了一些可以在单独线程中运行的内容 from PySide2.QtWidgets import QDialog, QApplication, QMainWindow from PySide2.QtCore import Qt, QThread, SIGNAL import time class MyClient(): '''Members of this class get

我正试图让一个长时间运行的方法在一个单独的线程中运行。该功能正在工作,但仍会导致GUI在方法运行时冻结。我是否遗漏了一些可以在单独线程中运行的内容

from PySide2.QtWidgets import QDialog, QApplication, QMainWindow
from PySide2.QtCore import Qt, QThread, SIGNAL
import time

class MyClient():
    '''Members of this class get passed to the QThread subclass instance in order to "doSomething" in a separate thread'''
    def __init__(self, name):
        self.name = name

    def doSomething(self):
        time.sleep(10) # but really do something more useful
        return self.name

class WorkerThread(QThread):
    '''Supposed to perform operation in a separate thread so GUI remains responsive.'''

    def __init__(self, client):
        super().__init__()
        self.client = client

    def __del__(self):
        self.wait()

    def run(self):
        print("Running!!!")
        return self.client.doSomething()

class MyForm(QMainWindow):
    def __init__(self, clients):
        super().__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.clients = clients

        # Connect button to method
        self.ui.btn_fetch.clicked.connect(self.fetch)

        self.show()
        self.fetch()

    def printName(self, name):
        print(name)

    def fetch(self):
        for client in self.clients:
            self.workerThread = WorkerThread(client)

            self.connect(self.workerThread, SIGNAL("printName(QString)"), self.printName)

            print("Starting thread")
            self.workerThread.start()
            # GUI becomes unresponsive here until the workerThread finishes.
            print("Thread started")

if __name__ == "__main__":

    clients = [MyClient('foo'), MyClient('bar'), MyClient('baz')]

    app = QApplication(sys.argv)
    w = MyForm(clients)
    w.show()
    sys.exit(app.exec_())

以下是使用PyQt5/PySide2信号的工作示例:

import sys
import time

from PyQt5.QtWidgets import QDialog, QApplication, QMainWindow
from PyQt5.QtCore import Qt, QThread, QObject, pyqtSignal

# If you need Pyside2 like in your example (untested):
# from PySide2.QtWidgets import QDialog, QApplication, QMainWindow
# from PySide2.QtCore import Qt, QThread, QObject, Signal


class MyClient:
    """Members of this class get passed to the QThread subclass instance
    in order to "doSomething" in a separate thread"""
    def __init__(self, name):
        self.name = name

    def doSomething(self):
        time.sleep(10)  # but really do something more useful
        return self.name


class WorkerThread(QThread):
    didSomething = pyqtSignal(str)

    """Supposed to perform operation in a separate thread so GUI remains responsive."""
    def __init__(self, client):
        super().__init__()
        self.client = client

    def run(self):
        print("Running!!!")
        self.didSomething.emit(self.client.doSomething())


class MyForm(QMainWindow):
    def __init__(self, clients):
        super().__init__()
        self.clients = clients

        # self.ui = Ui_MainWindow()
        # self.ui.setupUi(self)

        # Connect button to method
        # self.ui.btn_fetch.clicked.connect(self.fetch)

        self.workerThreads = []

        self.fetch()

    def printName(self, name):
        print(name)

    def removeThread(self, workerThread):
        def removeWorkerThread():
            self.workerThreads.remove(workerThread)
            print('Thread removed. Total active threads: {}'.format(len(self.workerThreads)))
        return removeWorkerThread

    def fetch(self):
        for client in self.clients:
            workerThread = WorkerThread(client)
            workerThread.didSomething.connect(self.printName)
            workerThread.finished.connect(self.removeThread(workerThread))
            self.workerThreads.append(workerThread)

            print("Starting thread")
            workerThread.start()

            # GUI becomes unresponsive here until the workerThread finishes.
            print("Thread started")


if __name__ == "__main__":
    myClients = [MyClient('foo'), MyClient('bar'), MyClient('baz')]

    app = QApplication(sys.argv)
    w = MyForm(myClients)
    w.show()
    sys.exit(app.exec_())

谢谢你,伊斯玛!我将在周一尝试这一点。经过测试,并对信号插槽架构进行了大量扩展,它开始工作了。非常感谢你的帮助!