Вот рабочий пример использования сигналов 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_())