Python 如何通过多线程任务发出PyQT信号

Python 如何通过多线程任务发出PyQT信号,python,pyqt,pyqt5,concurrent.futures,Python,Pyqt,Pyqt5,Concurrent.futures,我试图通过多线程方式发出PyQT信号。我创建了一个执行计算的函数(例如func)。以及另一个接受该任务并在多个线程中运行该任务的函数(例如函数) 当我使用父线程时,代码运行良好。但是,当我使用多线程时,计算效果很好,但信号不会发出 我需要使用多线程,因为我正在编写的函数执行计算量大的任务 请在下面找到示例代码(我在本例中使用了简单的打印功能) 您必须清楚以下概念:信号需要一个事件循环才能工作。 考虑到上述情况,解决方案如下: 穿线,穿线 您不应该使用join(),因为它会阻塞事件循环所在的主

我试图通过多线程方式发出PyQT信号。我创建了一个执行计算的函数(例如func)。以及另一个接受该任务并在多个线程中运行该任务的函数(例如函数)

当我使用父线程时,代码运行良好。但是,当我使用多线程时,计算效果很好,但信号不会发出

我需要使用多线程,因为我正在编写的函数执行计算量大的任务

请在下面找到示例代码(我在本例中使用了简单的打印功能)


您必须清楚以下概念:信号需要一个事件循环才能工作。

考虑到上述情况,解决方案如下:

  • 穿线,穿线
您不应该使用join(),因为它会阻塞事件循环所在的主线程,并且由于上述原因,信号将无法工作

从PyQt5导入QtCore
从线程导入线程
类Plot2D(QtCore.QObject):
完成=QtCore.pyqtSignal(浮点)
def功能(自我):
线程(target=self.func).start()
def func(自我):
n=10
v=1*100/(n-1)
对于范围(n)中的i:
打印(“线程”)
自完成发射(v)
@QtCore.pyqtSlot()
def fprint(自身):
印刷品(“作品”)
如果名称=“\uuuuu main\uuuuuuuu”:
导入系统
app=QtCore.QCoreApplication(sys.argv)
obj=Plot2D()
对象完成连接(对象打印)
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
thread
thread
works
thread
works
thread
works
thread
works
thread
thread
works
thread
works
thread
works
thread
works
works
works
  • 期货
不要使用with,因为它会使执行器阻塞主线程(我们已经知道它会产生什么问题),它还会调用
executor.shutdown(wait=False)

从PyQt5导入QtCore
进口期货
类Plot2D(QtCore.QObject):
完成=QtCore.pyqtSignal(浮点)
def功能(自我):
executor=concurrent.futures.ThreadPoolExecutor(最大工作线程数=3)
f=执行者提交(self.func)
执行器关闭(等待=错误)
def func(自我):
n=10
v=1*100/(n-1)
对于范围(n)中的i:
打印(“线程”)
自完成发射(v)
@QtCore.pyqtSlot()
def fprint(自身):
印刷品(“作品”)
如果名称=“\uuuuu main\uuuuuuuu”:
导入系统
app=QtCore.QCoreApplication(sys.argv)
obj=Plot2D()
对象完成连接(对象打印)
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
thread
thread
works
thread
works
thread
works
thread
works
thread
thread
works
thread
works
thread
works
thread
works
works
works

您必须清楚以下概念:信号需要一个事件循环才能工作。

考虑到上述情况,解决方案如下:

  • 穿线,穿线
您不应该使用join(),因为它会阻塞事件循环所在的主线程,并且由于上述原因,信号将无法工作

从PyQt5导入QtCore
从线程导入线程
类Plot2D(QtCore.QObject):
完成=QtCore.pyqtSignal(浮点)
def功能(自我):
线程(target=self.func).start()
def func(自我):
n=10
v=1*100/(n-1)
对于范围(n)中的i:
打印(“线程”)
自完成发射(v)
@QtCore.pyqtSlot()
def fprint(自身):
印刷品(“作品”)
如果名称=“\uuuuu main\uuuuuuuu”:
导入系统
app=QtCore.QCoreApplication(sys.argv)
obj=Plot2D()
对象完成连接(对象打印)
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
thread
thread
works
thread
works
thread
works
thread
works
thread
thread
works
thread
works
thread
works
thread
works
works
works
  • 期货
不要使用with,因为它会使执行器阻塞主线程(我们已经知道它会产生什么问题),它还会调用
executor.shutdown(wait=False)

从PyQt5导入QtCore
进口期货
类Plot2D(QtCore.QObject):
完成=QtCore.pyqtSignal(浮点)
def功能(自我):
executor=concurrent.futures.ThreadPoolExecutor(最大工作线程数=3)
f=执行者提交(self.func)
执行器关闭(等待=错误)
def func(自我):
n=10
v=1*100/(n-1)
对于范围(n)中的i:
打印(“线程”)
自完成发射(v)
@QtCore.pyqtSlot()
def fprint(自身):
印刷品(“作品”)
如果名称=“\uuuuu main\uuuuuuuu”:
导入系统
app=QtCore.QCoreApplication(sys.argv)
obj=Plot2D()
对象完成连接(对象打印)
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
thread
thread
works
thread
works
thread
works
thread
works
thread
thread
works
thread
works
thread
works
thread
works
works
works

谢谢你的回复。实际的代码非常复杂,所以我试图简化它。因此,代码的其余部分是。当发出此信号时,列表将用发出的值更新。并使用此值更新progressbar。因此,在这种情况下,progressbar不会更新。当使用父线程时,progressbar会更新,我已经修改了代码并进行了解释。当使用self.func()发出信号时,代码将打印(线程工作线程工作……)。但当它不是使用executor发出时,代码会打印(线程…)。请检查是的,它正在工作,我已经修改过了。请对父线程进行注释,然后对执行器进行注释并运行代码,您将使用bothI看到差异。您对Qt的工作方式一无所知。感谢您的回复。实际的代码非常复杂,所以我试图简化它。因此,代码的其余部分是。当发出此信号时,列表将用发出的值更新。并使用此值更新progressbar。因此,在这种情况下,progressbar不会更新。当使用父线程时,progressbar会更新,我已经修改了代码并进行了解释。当使用self.func()发出信号时,代码将打印(线程工作线程工作……)。但当它不是使用executor发出时,代码会打印(线程…)。请检查是的,它正在工作,我已经修改过了。请注释父线程,然后注释执行器并运行t