Python 正在创建wx.App的多个实例-可以吗?
因此,我需要实现以下场景: -多个任务作为进程同时运行。 -每个任务都应显示一个带有“取消”按钮的进度条,单击该按钮可终止任务 为了实现响应性GUI,我在一个单独的线程中为每个进程运行任务,似乎还需要为每个进程创建一个单独的Python 正在创建wx.App的多个实例-可以吗?,python,multithreading,python-2.7,wxpython,Python,Multithreading,Python 2.7,Wxpython,因此,我需要实现以下场景: -多个任务作为进程同时运行。 -每个任务都应显示一个带有“取消”按钮的进度条,单击该按钮可终止任务 为了实现响应性GUI,我在一个单独的线程中为每个进程运行任务,似乎还需要为每个进程创建一个单独的wx.App,否则该线程似乎没有运行。此设置工作正常,但是: a) 我不确定多个wx.App是否是一个好主意 b) 如果有更好的方法来实现我的目标 MWE如下(注意:在这个示例代码中,我本可以使用wx.ProgressDialog的Update方法来确定是否按下了“取消”按钮
wx.App
,否则该线程似乎没有运行。此设置工作正常,但是:
a) 我不确定多个wx.App
是否是一个好主意
b) 如果有更好的方法来实现我的目标
MWE如下(注意:在这个示例代码中,我本可以使用wx.ProgressDialog
的Update
方法来确定是否按下了“取消”按钮,但对于我的实际应用程序不能这样做)
不,在一个进程中有多个
wx.App
不是一个好主意。即使在前一个任务完成后创建一个新任务,有时也会出现问题
但是,由于您使用的是
多进程
,因此不完全相同。除非我遗漏了什么,否则在您的情况下,每个操作系统进程都只有一个wx.App
,并且由于父进程没有创建wx.App
,因此它们不会试图继承该进程(这可能会导致更多问题)。感谢您的输入。实际上,对于我的实际应用程序(不是这里的代码),父进程确实创建了一个wx.App
——我将报告出现的任何问题。然而,到目前为止,我的问题是进程的终止——当用户单击“取消”时,进程停止运行,但python任务仍然在后台运行。我可能不得不在另一个问题中问这个问题。
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()