2016-12-15 25 views
0

所以我需要實現以下情形: - 多個任務作爲進程同時運行。 - 每個任務應該有一個「取消」按鈕,可以顯示一個進度條,點擊它應該終止它。創建wx.App的多個實例 - 可以嗎?

爲了實現響應式圖形用戶界面,我在單獨的線程中爲每個進程運行任務,似乎我還需要爲每個進程創建一個單獨的wx.App,否則線程似乎沒有運行。這種設置工作正常,但:

一)我不知道是否多wx.App的是一個好主意或

B)如果有實現我的目標的更好的方法。 (注意:在這個示例代碼中,我可以使用Update方法wx.ProgressDialog來確定是否按下了「取消」按鈕,但是對於我的真實應用程序卻不能這樣做)。

import wx, multiprocessing, time, psutil 
from multiprocessing import Queue 
from threading import Thread 
from wx.lib.pubsub import pub as Publisher 

#runs the task 
def task_runner(q): 
    pid = multiprocessing.current_process().pid 
    q.put(pid) 

    while True: 
     print("Process Running") 
     time.sleep(1) 
     wx.CallAfter(Publisher.sendMessage, "update") #call to update the bar 

class TestPanel(): 

    def __init__(self,name): 
     self.q = Queue() 
     self.count=0 
     max = 80 

     # dialog to see progress and cancel the task 
     self.dlg = wx.GenericProgressDialog(name, 
           "An informative message", 
           maximum = max, 
           parent=None, 
           style = wx.PD_CAN_ABORT 
           | wx.PD_APP_MODAL 
           | wx.PD_ELAPSED_TIME 
           ) 

     #set listener to dialog's "Cancel" button 
     for child in self.dlg.GetChildren(): 
      if isinstance(child, wx.Button): 
       cancel_function = lambda evt, parent=self.dlg: self.onClose(evt, parent) 
       child.Bind(wx.EVT_BUTTON, cancel_function) 

     #subscribe to update the progress bar from the thread 
     Publisher.subscribe(self.updateProgress, "update") 


     # start thread which runs some task 
     p = Thread(target=task_runner, args=(self.q,)) 
     p.start() 


    #updates the progress bar 
    def updateProgress(self): 
     print("updating progress") 
     self.count=self.count+10 
     self.dlg.Update(self.count) 

    #kills the process 
    def kill(self, proc_pid): 
      process = psutil.Process(proc_pid) 
      for proc in process.children(recursive=True): 
       proc.kill() 
      process.kill() 

    #closing the dialog event 
    def onClose(self, event, dialog): 
     """""" 
     print "Closing dialog!" 
     pid = self.q.get() 
     self.kill(pid) 
     dialog.Destroy() 

# run process, each process creates its own wx.App 
def runProcess(name): 
    app = wx.App(False) 
    TestPanel(name) 
    app.MainLoop() 


# worker class to use for multiprocessing pool 
class Worker(): 
    def __call__(self, name): 
     return runProcess(name) 


if __name__ == '__main__': 
    items=['Bar1', 'Bar2'] 
    pool = multiprocessing.Pool(processes=2) 
    result = pool.map(Worker(), items) #create two processes 
    pool.close() 

回答

1

不,一個進程中有多個wx.App不是一個好主意。甚至在事先完成後創建一個新的有時可能會有問題。

但是,由於您使用multiprocess這是不太一樣的。除非我失去了一些東西,每個操作系統進程也只有一個wx.App在你的情況下,由於父進程也沒有創造一個wx.App那麼他們是不是要繼承一個(這可能會造成更大的問題。)

+0

感謝您的輸入。其實我真正的應用程序(不是這裏的代碼),父進程** **不創建一個'wx.App' - 我就報告提出的任何問題。到目前爲止,但我的問題是過程的終止 - 他們停止運行,當用戶點擊「取消」,但蟒的任務仍然保持在後臺運行。我可能不得不在單獨的問題中詢問這個問題。 –

相關問題