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

问题描述 投票:0回答:1

我想在单击切换按钮后执行任务,并在任务完成后将其切换为关闭状态,因此我在新进程中执行任务,因为我不想让它阻塞UI,event.GetEventObject().SetValue(False)似乎可以正确更新Toggle的值,但不会反映在UI上。

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()

更改Toggle的值后对event.GetEventObject().Update()event.GetEventObject().Refresh()的调用似乎没有任何改变。

event中的actionupdate_toggle的ID相同。

Python版本: 3.7

WxPython版本: 4.0.1

python python-3.x wxpython python-multiprocessing wxpython-phoenix
1个回答
1
投票

[您必须记住,您的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
© www.soinside.com 2019 - 2024. All rights reserved.