似乎我已经很危险地将subprocessing的Pool()启动的所有子进程链接到PyQt进度条小部件。下面是示例代码。显然,几乎没有什么流动阻止了我的梦想的实现。在
概念:
externalFunc()执行所有主要任务。通过将其值存储到poolDict变量中,它不时地将其“progress values”发送到MainWindow()实例,方法是将其值存储到声明为:
poolDict=manager.dict()
同时,myEventListener()方法正在后台运行,等待值“post”。一旦值“received”myEventListener()将ProgressBar更新为接收到的值并将其重置为零(以避免重复的ProgressBar更新)。 在尝试更新ProgressBar之前,MyEventListener(self)验证ProgressBar尚未达到其最大值100,然后继续使用:
^{pr2}$不幸的是,即使externalFunc()提供的值超过了(160),ProgressBar也从未达到100。除此之外,无法退出MainWindow()while循环。在
在阅读此代码之前,请小心运行此代码,因为它可能会在您的计算机上生成多个python进程,这些进程将不得不终止。
问题:
import sys, time
from PyQt4 import QtCore, QtGui
import multiprocessing as mp
from multiprocessing import Pool
manager = mp.Manager()
poolDict=manager.dict()
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
def externalFunc(each):
for i in range(16):
print i
poolDict[each]=10+i
time.sleep(0.5)
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
# self.myList=[.1, .3, .5, 1.0, 1.5, 2.9, 3.1]
self.myList=[1]
self.main_layout = QtGui.QVBoxLayout()
self.pBars={}
self.state=True
for each in self.myList:
pb=PbWidget(total=101)
self.main_layout.addWidget(pb)
self.pBars[each]={'pb':pb, 'value':0, 'total_value':0}
ok_button = QtGui.QPushButton("OK")
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 myEvenListener(self):
"""This function runs at the background as an infinite while loop. It constantly reads
a value stored in poolDict variable to which externalFunc() writes a new value every second.
The value represents a 'Progress' and needs to be passes to Progress Bar widget to which only MainWindow()
class has an access. After a Value was read it is used to update a Progress Bar.
After a progress bar was updated the Value is reset to zero.
The Problem: 'if pb.value()>=100' statement is used to make sure the function doesn't loop if the ProgressBar
is already reached 100. By some reason the bar never reaches its maximum 100 even while externalFunc() calls
enough times to reach this number. An ussue # 2: There is no meachanism to exit this while loop without adding
three more variables... Can it be achieved with what we already have?
"""
while self.state:
for each in self.pBars:
pb = self.pBars[each]['pb']
print "\n Current Bar value =", pb.value()
if pb.value()>=100:
print 'skipping'
continue
value=None
if each in poolDict.keys():
# read delivered value
delivered_value=poolDict[each]
# reset delivered value
poolDict[each]=0
# update bar with delivered value
if ( 101-pb.value() ) < delivered_value:
print "\n\t UPDATING WITH "
pb.update_bar( 101-pb.value() )
print "\n\t AFTER ", pb.value()
else:
pb.update_bar( delivered_value )
# print '\n\t\t\t Updating bar using this value', delivered_value
def OK(self):
pool = Pool(processes=3)
pool.map_async( externalFunc, self.myList)
self.myEvenListener()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = MainWindow()
window.resize(480, 320)
window.show()
sys.exit(app.exec_())
这是一个修订的代码。它似乎运转良好,而且相当稳定。在
相关问题 更多 >
编程相关推荐