2016-12-15 75 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' - 我就报告提出的任何问题。到目前为止,但我的问题是过程的终止 - 他们停止运行,当用户点击“取消”,但蟒的任务仍然保持在后台运行。我可能不得不在单独的问题中询问这个问题。 –

相关问题