如何通过多线程任务发出 pyqtsignal
How to emit a pyqtsignal through multi-threading task
我正在尝试通过多线程方式发出 pyqtsignal。我创建了一个执行计算的函数(例如 func)。另一个函数在多个线程中接受该任务并运行它(例如Function)。
当我使用父线程时代码运行良好。但是,当我使用多线程时,计算效果很好,但没有发出信号。
我需要使用多线程,因为我正在编写的函数执行计算量大的任务。
请在下面找到示例代码(我在这个例子中使用了简单的打印功能)
from PyQt5.QtCore import QObject, pyqtSignal,pyqtSlot
import time
from threading import Thread
import sys
import math
import concurrent.futures
class Plot2D(QObject):
finish=pyqtSignal(float)
def __init__(self):
super(Plot2D,self).__init__()
def Function(self):
st = time.time()
# Using parent thread
# self.func()
# Using multi-thread 1
#t=Thread(target=self.func)
#t.start()
#t.join()
# Using multi-thread 2
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
f = executor.submit(self.func)
en = time.time()
print(en-st)
def func(self):
n=10
v=(1*100/(n-1))
for i in range(n):
print('thread')
self.finish.emit(v)
def fprint(self):
print('works')
obj=Plot2D()
obj.finish.connect(obj.fprint)
obj.Function()
你必须清楚以下概念:信号需要事件循环才能工作。
综合以上,解决办法是:
- threading.Thread
您不应使用 join(),因为它会阻塞 event-loop 所在的主线程,并且由于上述原因,信号将不起作用。
from PyQt5 import QtCore
from threading import Thread
class Plot2D(QtCore.QObject):
finished = QtCore.pyqtSignal(float)
def Function(self):
Thread(target=self.func).start()
def func(self):
n = 10
v = 1 * 100 / (n - 1)
for i in range(n):
print("thread")
self.finished.emit(v)
@QtCore.pyqtSlot()
def fprint(self):
print("works")
if __name__ == "__main__":
import sys
app = QtCore.QCoreApplication(sys.argv)
obj = Plot2D()
obj.finished.connect(obj.fprint)
obj.Function()
sys.exit(app.exec_())
输出:
thread
thread
thread
works
thread
works
thread
works
thread
thread
works
thread
works
thread
thread
works
works
works
works
works
- concurrent.futures
不要使用 with 因为它会使执行程序阻塞主线程(我们已经知道它会产生什么问题),它还会调用 executor.shutdown(wait = False)
from PyQt5 import QtCore
import concurrent.futures
class Plot2D(QtCore.QObject):
finished = QtCore.pyqtSignal(float)
def Function(self):
executor = concurrent.futures.ThreadPoolExecutor(max_workers=3)
f = executor.submit(self.func)
executor.shutdown(wait=False)
def func(self):
n = 10
v = 1 * 100 / (n - 1)
for i in range(n):
print("thread")
self.finished.emit(v)
@QtCore.pyqtSlot()
def fprint(self):
print("works")
if __name__ == "__main__":
import sys
app = QtCore.QCoreApplication(sys.argv)
obj = Plot2D()
obj.finished.connect(obj.fprint)
obj.Function()
sys.exit(app.exec_())
输出:
thread
thread
works
thread
works
thread
works
thread
works
thread
thread
works
thread
works
thread
works
thread
works
works
works
我正在尝试通过多线程方式发出 pyqtsignal。我创建了一个执行计算的函数(例如 func)。另一个函数在多个线程中接受该任务并运行它(例如Function)。
当我使用父线程时代码运行良好。但是,当我使用多线程时,计算效果很好,但没有发出信号。
我需要使用多线程,因为我正在编写的函数执行计算量大的任务。
请在下面找到示例代码(我在这个例子中使用了简单的打印功能)
from PyQt5.QtCore import QObject, pyqtSignal,pyqtSlot
import time
from threading import Thread
import sys
import math
import concurrent.futures
class Plot2D(QObject):
finish=pyqtSignal(float)
def __init__(self):
super(Plot2D,self).__init__()
def Function(self):
st = time.time()
# Using parent thread
# self.func()
# Using multi-thread 1
#t=Thread(target=self.func)
#t.start()
#t.join()
# Using multi-thread 2
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
f = executor.submit(self.func)
en = time.time()
print(en-st)
def func(self):
n=10
v=(1*100/(n-1))
for i in range(n):
print('thread')
self.finish.emit(v)
def fprint(self):
print('works')
obj=Plot2D()
obj.finish.connect(obj.fprint)
obj.Function()
你必须清楚以下概念:信号需要事件循环才能工作。
综合以上,解决办法是:
- threading.Thread
您不应使用 join(),因为它会阻塞 event-loop 所在的主线程,并且由于上述原因,信号将不起作用。
from PyQt5 import QtCore
from threading import Thread
class Plot2D(QtCore.QObject):
finished = QtCore.pyqtSignal(float)
def Function(self):
Thread(target=self.func).start()
def func(self):
n = 10
v = 1 * 100 / (n - 1)
for i in range(n):
print("thread")
self.finished.emit(v)
@QtCore.pyqtSlot()
def fprint(self):
print("works")
if __name__ == "__main__":
import sys
app = QtCore.QCoreApplication(sys.argv)
obj = Plot2D()
obj.finished.connect(obj.fprint)
obj.Function()
sys.exit(app.exec_())
输出:
thread
thread
thread
works
thread
works
thread
works
thread
thread
works
thread
works
thread
thread
works
works
works
works
works
- concurrent.futures
不要使用 with 因为它会使执行程序阻塞主线程(我们已经知道它会产生什么问题),它还会调用 executor.shutdown(wait = False)
from PyQt5 import QtCore
import concurrent.futures
class Plot2D(QtCore.QObject):
finished = QtCore.pyqtSignal(float)
def Function(self):
executor = concurrent.futures.ThreadPoolExecutor(max_workers=3)
f = executor.submit(self.func)
executor.shutdown(wait=False)
def func(self):
n = 10
v = 1 * 100 / (n - 1)
for i in range(n):
print("thread")
self.finished.emit(v)
@QtCore.pyqtSlot()
def fprint(self):
print("works")
if __name__ == "__main__":
import sys
app = QtCore.QCoreApplication(sys.argv)
obj = Plot2D()
obj.finished.connect(obj.fprint)
obj.Function()
sys.exit(app.exec_())
输出:
thread
thread
works
thread
works
thread
works
thread
works
thread
thread
works
thread
works
thread
works
thread
works
works
works