2014-06-05 44 views
1

下面的代碼創建一個帶有三個進度條的對話窗口。每個進度欄都鏈接到使用multiprocessing Pool開始的三個進程之一。如何停止Python中的單個多進程進程?

enter image description here

當進度條右鍵單擊一個「停止進程」菜單長大。菜單鏈接到非功能stopProc()功能。目標是利用'Stop Process()'功能來停止右鍵點擊的過程。我將不勝感激,如果你將展示如何實現這一任務:

enter image description here

from PyQt4 import QtGui, QtCore 
import time 
import multiprocessing as mp 
poolPbDict=mp.Manager().dict() 

def myFunct(inst): 
    print 'myFunct():', inst.getName(), inst.getPbId(), '\n' 
    for i in range(110): 
     for n in range(150000): pass 
     poolPbDict[ inst.getPbId() ]=i 
    print '\n\t myFunct(): completed',inst.getName(),inst.getPbId(),poolPbDict[ inst.getPbId() ],'\n' 


class PbWidget(QtGui.QProgressBar): 
    def __init__(self, parent=None, total=20): 
     super(PbWidget, self).__init__() 
     self.setMinimum(1) 
     self.setMaximum(105)   
     self._active = False 
    def update_bar(self, argValue): 
     self.setValue(argValue) 
     QtGui.qApp.processEvents() 
    def closeEvent(self, event): 
     self._active = False 

class ProgressBarTree(QtGui.QTreeWidget): 
    def __init__(self, parent=None): 
     QtGui.QTreeWidget.__init__(self) 
     self.items=[] 
     self.pBars=[] 
     self.setColumnCount(2) 
     self.setHeaderLabels(['Name','Progress']) 
     self.header().setStretchLastSection(True) 

    def createJobItem(self, inst): 
     item=QtGui.QTreeWidgetItem() 
     item.setText(0, inst.getName()) 
     item.setData(1, QtCore.Qt.UserRole, inst) 
     self.addTopLevelItem(item) 

     pb=PbWidget() 
     self.setItemWidget(item, 1, pb) 
     inst.setPbId(id(pb)) 

     self.items.append(item) 
     self.pBars.append(pb)   

     return inst 

    def getpBars(self): 
     return self.pBars 

class MyObject(object): 
    def __init__(self, name): 
     super(MyObject, self).__init__() 
     self.name = name 
     self.PbId = None 
    def setPbId(self, arg): 
     self.PbId=arg 
    def getPbId(self): 
     return self.PbId 
    def getName(self): 
     return self.name 

class Window(QtGui.QWidget): 
    def __init__(self): 
     # declare instances 
     self.instList=[] 
     for each in ['One','Two','Three']: 
      self.instList.append(MyObject(each)) 

     QtGui.QWidget.__init__(self) 
     layout = QtGui.QVBoxLayout(self) 
     self.pbTree = ProgressBarTree() 
     self.pbTree.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) 
     self.pbTree.connect(self.pbTree,QtCore.SIGNAL('customContextMenuRequested(QPoint)'),self.showMenu) 

     self.menu=QtGui.QMenu() 
     menuItem1=self.menu.addAction('Stop Process')   
     self.connect(menuItem1,QtCore.SIGNAL('triggered()'),self.stopProc) 

     layout.addWidget(self.pbTree) 
     # per instance create progress bar 
     for inst in self.instList: 
      inst=self.pbTree.createJobItem(inst) 
     # button  
     button=QtGui.QPushButton("Run Processes") 
     button.clicked.connect(self.runProcs) 
     layout.addWidget(button) 

    def showMenu(self, QPos): 
     parentPosition=self.pbTree.mapToGlobal(QtCore.QPoint(0, 0))   
     menuPosition=parentPosition+QPos 
     self.menu.move(menuPosition) 
     self.menu.show() 

    def stopProc(self): 
     print '\n\t stopProc()' 

    def setup(self, event): 
     global unpaused 
     unpaused = event 

    def runProcs(self): 
     self.resetBars()  
     self.event=mp.Event() 
     self.pool=mp.Pool(2, self.setup, (self.event,)) 
     self.pool.map_async(myFunct, self.instList) 
     self.event.set()  
     self.eventListener() 
     poolPbDict.clear() 

    def eventListener(self): 
     global poolPbDict 
     state=True 
     while state: 
      if not poolPbDict: 
       time.sleep(0.2) 
       continue 
      self.updateBars() 
      check=True 
      if len(poolPbDict.keys())<len(self.instList):     
       check=False 
      for value in poolPbDict.values(): 
       if value<105: 
        check=False 
        time.sleep(0.2) 
        break   
      if check: 
       state=False 
       print '\n\t eventListener() has been stopped \n' 
       break 

    def updateBars(self): 
     global poolPbDict 
     pBars=self.pbTree.getpBars() 
     for pb in pBars: 
      pbId=id(pb) 
      value=poolPbDict.get(pbId) 
      if value: 
       if value>=105: 
        pb.update_bar(105)         
       else: 
        pb.update_bar(value) 

    def resetBars(self): 
     for pb in self.pbTree.getpBars(): 
      pb.reset() 

if __name__ == '__main__': 
    import sys 
    app = QtGui.QApplication(sys.argv) 
    window = Window() 
    window.resize(600,200) 
    window.show() 
    sys.exit(app.exec_()) 

回答