2016-12-15 14 views
0

次のシナリオを実装する必要があります。 - 複数のタスクが同時にプロセスとして実行されています。 - 各タスクには、「キャンセル」ボタンが付いた進行状況バーが表示され、クリックすると終了する必要があります。wx.Appの複数のインスタンスを作成する - それは問題ありませんか?

応答性の高いGUIを実現するために、私は別のスレッドで各プロセスのタスクを実行し、別のプロセスでも同様にwx.Appを作成する必要があるようです。そうでなければスレッドは実行されていないようです。このセットアップは、しかし、正常に動作します:

A)私は私の目標を達成するためのより良い方法がある場合は、複数のwx.Appのは良いアイデアや

B)であるかどうかを確認していません。

以下のMWE(注:このサンプルコードでは、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

いいえ、1つのプロセスで複数のwx.Appを持つことはお勧めできません。前のことが終わった後に新しいものを作成することさえ問題になることがあります。

しかし、multiprocessを使用しているため、それほど同じではありません。私が何か不足している場合を除き、それぞれのOSプロセスはあなたのケースではwx.Appを1つしか持たず、親プロセスはwx.Appを作成していないので、そのプロセスを継承しようとしていません。

+0

入力いただきありがとうございます。実際に私の実際のアプリケーション(ここのコードではない)のために、親プロセス**は 'wx.App'を作成します - 発生した問題を報告します。これまでのところ私の問題はプロセスの終了です - ユーザーが "キャンセル"をクリックしたときに実行を停止しますが、Pythonのタスクはバックグラウンドで実行し続けます。私は別の質問でこれについて尋ねなければならないかもしれません。 –

関連する問題