Python GUI 中的 QThread
Python QThread in GUI
我正在尝试按照 this guide 的方法在单独的线程中使用长 运行ning 方法 运行。该功能正在运行,但它仍然导致 GUI 在方法 运行ning 时冻结。我是否遗漏了一些可以让这个 运行 在单独的线程中的东西?
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_())
我正在尝试按照 this guide 的方法在单独的线程中使用长 运行ning 方法 运行。该功能正在运行,但它仍然导致 GUI 在方法 运行ning 时冻结。我是否遗漏了一些可以让这个 运行 在单独的线程中的东西?
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_())