流程完成后,如何更新切换按钮的状态?

时间:2020-02-19 09:08:07

标签: python python-3.x python-multiprocessing wxpython

我想在单击“切换按钮”后执行任务,然后在任务完成后将其关闭,因此我希望在新进程中执行该任务,因为我不想让它阻塞UI,{{ 1}}似乎可以正确更新Toggle的值,但不会反映在UI上。

event.GetEventObject().SetValue(False)

更改Toggle的值后调用from multiprocessing import Process import time import wx class MyFrame(wx.Frame): def __init__(self, *args, **kwds): kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE wx.Frame.__init__(self, *args, **kwds) self.toggle_button = wx.ToggleButton(self, wx.ID_ANY, "OK") control = Control() self.Bind(wx.EVT_TOGGLEBUTTON, control.action, self.toggle_button) self.SetTitle("Update UI with a process") sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.toggle_button, 0, 0, 0) self.SetSizer(sizer) self.Layout() class Control(): def update_toggle(self, duration, event): time.sleep(duration) event.GetEventObject().SetValue(False) print("Toggled") def action(self, event): if event.GetEventObject().GetValue(): self.update_toggle_process = Process(target = self.update_toggle, args=(5, event,)) self.update_toggle_process.start() else: print("UnToggled") class MyApp(wx.App): def OnInit(self): self.frame = MyFrame(None, wx.ID_ANY, "") self.SetTopWindow(self.frame) self.frame.Show() return True if __name__ == "__main__": app = MyApp(0) app.MainLoop() event.GetEventObject().Update()似乎没有任何改变。

编辑

如果我使用event.GetEventObject().Refresh()而不是Thread,它可以正常工作,但是我选择了Process而不是Process,因为我希望能够在需要时将其干净地杀死

Python版本: 3.7

WxPython版本: 4.0.1

1 个答案:

答案 0 :(得分:3)

您必须记住,您的update_toggle在新进程中运行。简而言之,它具有数据的副本,因此,如果调用event.GetEventObject()。SetValue(False),它将在新进程中发生,而原来的带有Window和Button的进程将不知道。

您必须以某种方式将消息从新过程传递到原始过程。我建议您尝试的第一件事是:

        self.update_toggle_process.start()
        self.update_toggle_process.join()
        print("the process has finished")

这将阻止,但至少您会看到“ update_toggle_process”是否已完成以及该方法是否有效。在那之后,有几种可能性:

  • 设置时间并定期调用self.update_toggle_process.is_alive()
  • 创建一个新线程,从中调用update_toggle_process.start(),然后加入join()。完成后,告诉主线程切换按钮(请记住,您只能从wx中的主线程操作UI)
  • 也许您不需要新进程,一个线程就足够了
  • 查看多处理IPC