如何在多处理函数中使用 wxPython enable/disable 按钮?
How to enable/disable a button with wxPython in a multiprocessed function?
我试图在单击按钮时禁用它,并在使用多处理调用的函数完成后重新启用它。
目前,每次我尝试在函数中访问该按钮时,它基本上都会给我一个空引用。
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(parent=None, title='Title', size=(800, 500), style=wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.MINIMIZE_BOX)
panel = wx.Panel(self)
self.my_btn = wx.Button(panel, label='Label me')
self.my_btn.Bind(wx.EVT_BUTTON,self.on_press)
self.Show()
def two(self):
self.my_btn.Enable()
def on_press(self, event):
self.my_btn.Disable()
Process(target=one).start()
def one():
#something
MyFrame.two(MyFrame)
我希望按钮在完成后重新启用。但无论我尝试什么,它要么是 TypeError 要么是 AttributeError。
您必须牢记,一旦调用 Process(...).start(),就会有 2 个不相关的进程。他们不能直接访问彼此的变量。所以很容易理解的可能性是:
- 在on_press中做:self.process = Process(target=one); self.process.start()
- 启动一个计时器 (wx.Timer),定期检查 self.process 是否仍然是 运行 (self.process.is_alive())
- 一旦该进程不再存在,您可以启用该按钮。
您可能认为它不如 "poll" 和 self.process,但它几乎没有成本,如果您调用它,比如每秒 20 次,进程结束和按钮重新启用不会引起注意。
其他选择是启动另一个线程并执行 self.process.join()。但请记住,您不能只是从线程中调用 self.btn.Enable。使用 wx.CallAfter。 (一般来说只能从主线程调用wx函数)
您当然可以使用管道或队列在这两个进程之间进行通信,例如,如果您需要发回结果。
我试图在单击按钮时禁用它,并在使用多处理调用的函数完成后重新启用它。
目前,每次我尝试在函数中访问该按钮时,它基本上都会给我一个空引用。
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(parent=None, title='Title', size=(800, 500), style=wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.MINIMIZE_BOX)
panel = wx.Panel(self)
self.my_btn = wx.Button(panel, label='Label me')
self.my_btn.Bind(wx.EVT_BUTTON,self.on_press)
self.Show()
def two(self):
self.my_btn.Enable()
def on_press(self, event):
self.my_btn.Disable()
Process(target=one).start()
def one():
#something
MyFrame.two(MyFrame)
我希望按钮在完成后重新启用。但无论我尝试什么,它要么是 TypeError 要么是 AttributeError。
您必须牢记,一旦调用 Process(...).start(),就会有 2 个不相关的进程。他们不能直接访问彼此的变量。所以很容易理解的可能性是:
- 在on_press中做:self.process = Process(target=one); self.process.start()
- 启动一个计时器 (wx.Timer),定期检查 self.process 是否仍然是 运行 (self.process.is_alive())
- 一旦该进程不再存在,您可以启用该按钮。
您可能认为它不如 "poll" 和 self.process,但它几乎没有成本,如果您调用它,比如每秒 20 次,进程结束和按钮重新启用不会引起注意。
其他选择是启动另一个线程并执行 self.process.join()。但请记住,您不能只是从线程中调用 self.btn.Enable。使用 wx.CallAfter。 (一般来说只能从主线程调用wx函数)
您当然可以使用管道或队列在这两个进程之间进行通信,例如,如果您需要发回结果。