Python PyQt5使用一个QRunnable启动其他QRunnable
我正在为一个问题而挣扎(很多):我正在启动一个需要一些计算资源的过程,有时需要很多时间。因为我不能用一个按钮杀死一个正在运行的QRunnable,所以我想使用一个QRunnable,它可以并行启动不超过6个其他进程。下面是一个我所想的例子:Python PyQt5使用一个QRunnable启动其他QRunnable,python,multithreading,pyqt5,qrunnable,Python,Multithreading,Pyqt5,Qrunnable,我正在为一个问题而挣扎(很多):我正在启动一个需要一些计算资源的过程,有时需要很多时间。因为我不能用一个按钮杀死一个正在运行的QRunnable,所以我想使用一个QRunnable,它可以并行启动不超过6个其他进程。下面是一个我所想的例子: from PyQt5 import QtWidgets, QtCore from time import sleep from sys import argv, exc_info, exit import traceback threadp
from PyQt5 import QtWidgets, QtCore
from time import sleep
from sys import argv, exc_info, exit
import traceback
threadpool = QtCore.QThreadPool()
max_paralell_processes = 5
class MainWindow(QtWidgets.QMainWindow):
stopsignal = QtCore.pyqtSignal()
def __init__(self):
super(MainWindow, self).__init__()
self.trainers = {}
self.ntrainers = 10
self.startButton = QtWidgets .QPushButton('Start', self)
self.startButton.resize(self.startButton.sizeHint())
self.startButton.move(50, 50)
self.stopButton = QtWidgets.QPushButton('Stop', self)
self.stopButton.resize(self.stopButton.sizeHint())
self.stopButton.move(150, 50)
self.setGeometry(300, 300, 300, 200)
self.startButton.clicked.connect(self.create_trainers)
self.stopButton.clicked.connect(self.stop)
self.progressBar = QtWidgets.QProgressBar(self)
self.progressBar.setGeometry(50, 20, 250, 20)
self.count = 0
self.progressBar.setValue(self.count)
def create_trainers(self):
global threadpool
for m in range(self.ntrainers):
trainer = Trainer(self.the_long_process, m)
trainer.progress.connect( self.progress_bar)
trainer.finished.connect( self.finished_process)
self.trainers[m] = trainer
launcher = LaunchWorkers(self.trainers, range(self.ntrainers))
launcher.finished.connect(self.__all_processes_finished)
self.stopsignal.connect(launcher.stop)
threadpool.start(launcher)
def the_long_process(self, m):
print("In process {}".format(m))
sleep(2)
def progess_bar(self):
self.count += 1
self.progressBar.setValue(self.count/len(self.trainers)*100)
def finished_process(self):
pass
def stop(self):
self.stopsignal.emit()
class Trainer(QtCore.QRunnable):
finished = QtCore.pyqtSignal(str)
error = QtCore.pyqtSignal(tuple)
progress = QtCore.pyqtSignal()
def __init__(self, the_fn, m):
super(Trainer, self).__init__()
self.the_fn = the_fn
self.m = m
self.terminated = False
@QtCore.pyqtSlot()
def run(self):
try:
self.the_fn ( self.m )
except:
traceback.print_exc()
exctype, value = exc_info()[:2]
self.error.emit((exctype, value, traceback.format_exc()))
self.terminated = True
else:
self.progress.emit()
finally:
self.terminated = True
self.finished.emit( self.m)
class LaunchWorkers(QtCore.QRunnable):
finished = QtCore.pyqtSignal()
error = QtCore.pyqtSignal(tuple)
def __init__(self, trainers, some_list ):
super(LaunchWorkers, self).__init__()
self.trainers = trainers
self.some_list = some_list
self.stop = False
def stop(self):
self.stop = True
@QtCore.pyqtSlot()
def run(self):
global threadpool
finished_threads = 0
try:
for m in self.some_list :
if self.stop:
break
while finished_threads <= 6:
sleep(10)
finished_threads = 0
for t in self.trainers:
if self.trainers[t].terminated:
finished_threads += 1
threadpool.start( self.trainers[m] )
except:
traceback.print_exc()
exctype, value = exc_info()[:2]
self.error.emit((exctype, value, traceback.format_exc()))
finally:
self.finished.emit( )
def main():
app = QtWidgets.QApplication(argv)
ex = MainWindow()
ex.show()
exit(app.exec_())
if __name__ == '__main__':
main()
从PyQt5导入QtWidgets、QtCore
从时间上导入睡眠
从系统导入argv,exc_info,退出
导入回溯
threadpool=QtCore.QThreadPool()
最大平行过程=5
类MainWindow(QtWidgets.QMainWindow):
stopsignal=QtCore.pyqtSignal()
定义初始化(自):
超级(主窗口,自我)。\uuuu初始化
self.trainers={}
自我约束=10
self.startButton=qtwidts.QPushButton('Start',self)
self.startButton.resize(self.startButton.sizeHint())
自我启动按钮移动(50,50)
self.stopButton=qtwidts.QPushButton('Stop',self)
self.stopButton.resize(self.stopButton.sizeHint())
自动停止按钮移动(150,50)
self.setGeometry(300300300200)
self.startButton.clicked.connect(self.create_)
self.stop按钮。单击。连接(self.stop)
self.progressBar=qtwidts.QProgressBar(self)
self.progressBar.setGeometry(50、20、250、20)
self.count=0
self.progressBar.setValue(self.count)
def创建_培训师(自我):
全局线程池
对于范围内的m(自我约束):
培训师=培训师(self.the_long_流程,m)
trainer.progress.connect(self.progress\u栏)
培训师.完成.连接(自我.完成\u过程)
self.trainers[m]=培训师
发射器=发射工人(自我训练者,射程(自我训练者))
launcher.finished.connect(self.\u所有\u进程\u finished)
自动停止信号连接(启动器停止)
threadpool.start(启动程序)
定义长流程(self,m):
打印(“处理中{}”。格式(m))
睡眠(2)
def进度条(自):
self.count+=1
self.progressBar.setValue(self.count/len(self.trainers)*100)
def完成_过程(自):
通过
def停止(自):
self.stopsignal.emit()
课堂培训师(QtCore.QRunnable):
完成=QtCore.pyqtSignal(str)
错误=QtCore.pyqtSignal(元组)
progress=QtCore.pyqtSignal()
定义初始(self,the_fn,m):
超级(培训师,自我)。\uuuu初始
self.the_fn=the_fn
self.m=m
self.terminated=False
@QtCore.pyqtSlot()
def运行(自):
尝试:
self.the_fn(self.m)
除:
traceback.print_exc()
exctype,value=exc_info()[:2]
self.error.emit((exctype,value,traceback.format_exc())
self.terminated=True
其他:
self.progress.emit()
最后:
self.terminated=True
self.finished.emit(self.m)
类LaunchWorkers(QtCore.QRunnable):
finished=QtCore.pyqtSignal()
错误=QtCore.pyqtSignal(元组)
定义初始(自我、培训师、部分列表):
超级(LaunchWorkers,self)。\uuuu init\uuuu()
self.trainers=培训师
self.some\u list=some\u list
self.stop=False
def停止(自):
self.stop=True
@QtCore.pyqtSlot()
def运行(自):
全局线程池
成品螺纹=0
尝试:
对于self.some_列表中的m:
如果自动停止:
打破
完成螺纹时,请提供@eyllanesc Done。谢谢你的评论。