Python:如何将多个进度条链接到以线程开始的每个子流程
创建的进度条数量与myList中的实体数量相同。 单击“确定”按钮启动与myList中实体数量相同的子流程 问题: 1.在myList中,似乎启动的子进程比实体多得多。 2.无法使用一行更新ProgressBar(这就是为什么会对其进行注释):Python:如何将多个进度条链接到以线程开始的每个子流程,python,multithreading,qt,Python,Multithreading,Qt,创建的进度条数量与myList中的实体数量相同。 单击“确定”按钮启动与myList中实体数量相同的子流程 问题: 1.在myList中,似乎启动的子进程比实体多得多。 2.无法使用一行更新ProgressBar(这就是为什么会对其进行注释): 我没有看到子进程。线程不是子进程。您的问题是:“如何使用进度条显示线程中的进度?如果有多个线程,如何显示?”顺便说一句,为什么您需要线程?您是正确的!一个想法是将每个线程(错误地称为“子进程”)紧密连接到一个专用的进度条(进度条的数量与线程的数量相同)
我没有看到子进程。线程不是子进程。您的问题是:“如何使用进度条显示线程中的进度?如果有多个线程,如何显示?”顺便说一句,为什么您需要线程?您是正确的!一个想法是将每个线程(错误地称为“子进程”)紧密连接到一个专用的进度条(进度条的数量与线程的数量相同)。我已经用多处理模块实现了相同的功能。它工作得很好。但在多重处理中,我失去了共享相同变量/对象的能力。这让我相信我应该使用线程而不是多处理。。。既然已经提到,线程确实共享变量/对象。线程和多处理不是有着相同的概念吗:只是实现方式不同而已。代码方面如果它与
多处理
一起工作,那么它可能与线程
(+/-一些导入和重命名,例如进程
->线程
)。不同之处可能在于性能(可能会慢/快,具体取决于您的代码)。如果您的代码是CPU绑定的,并且您不使用可以在CPython中释放GIL的模块,那么线程化不是一个答案,因为一次只有一个线程可以运行纯Python代码。它不适用于由多处理创建的多个进程。每个Python进程都有自己的GIL。也就是说,我尝试并解决了问题X,但我认为解决方案Y会更好,所以我没有问X是否是唯一的解决方案,而是尝试用Y解决相同的问题,遇到了麻烦,现在问Y……)不幸的是,我没有太多的线程(以及多处理)经验。因此,我认为这将是一个很好的机会,让我深入探讨这个问题。似乎使用多处理很容易产生“非线性逻辑”代码。但线程模块在这方面并没有“更好”。虽然线程共享变量/对象的能力很诱人,但它并不完全是“即插即用”,需要一些时间来投资。。。不幸的是,我从来都不够!
pb.update_bar( self.pBars[each]['value'] )
import sys, os
from PyQt4 import QtCore, QtGui
import threading
import time
class PbWidget(QtGui.QProgressBar):
def __init__(self, parent=None, total=20):
super(PbWidget, self).__init__()
self.setMinimum(1)
self.setMaximum(total)
self._active = False
def update_bar(self, to_add_number):
while True:
time.sleep(0.01)
value = self.value() + to_add_number
self.setValue(value)
QtGui.qApp.processEvents()
if (not self._active or value >= self.maximum()):
break
self._active = False
def closeEvent(self, event):
self._active = False
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.myList = ['One','Two','Three','Four','Five','Six','Seven']
self.main_layout = QtGui.QVBoxLayout()
self.pBars={}
for each in self.myList:
pb=PbWidget(total=101)
self.main_layout.addWidget(pb)
self.pBars[each]={'pb':pb, 'name':each, 'value': 0}
ok_button = QtGui.QPushButton("Distribute")
ok_button.clicked.connect(self.OK)
self.main_layout.addWidget(ok_button)
central_widget = QtGui.QWidget()
central_widget.setLayout(self.main_layout)
self.setCentralWidget(central_widget)
def internalFunc(self, myEvent, each):
pb = self.pBars[each]['pb']
state=True
while state:
if self.pBars[each]['value']>=100: state=False
for i in range(12):
self.pBars[each]['value']+=10
print '\n\t ...Working on', each, self.pBars[each]['value'], '\n'
# pb.update_bar( self.pBars[each]['value'] )
time.sleep(0.5)
print "\n\t ProgressBar", each, 'has reached 100%. Its value =', self.pBars[each]['value'], '\n'
def OK(self):
for each in self.pBars:
self.myEvent=threading.Event()
self.c_thread=threading.Thread(target=self.internalFunc, args=(self.myEvent, each,))
self.c_thread.start()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = MainWindow()
window.resize(480, 320)
window.show()
sys.exit(app.exec_())