简体   繁体   English

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

[英]How to update the state of a Toggle Button after process completion?

I want to execute a task when a Toggle Button is clicked(on) and toggle it off after the task is completed, I execute the task in a new process because I don't want it to block the UI, event.GetEventObject().SetValue(False) seems to update correctly the value of the Toggle but it doesn't reflect on the UI.我想在单击(打开)切换按钮时执行任务并在任务完成后将其关闭,我在新进程中执行任务,因为我不希望它阻塞 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()

A call to event.GetEventObject().Update() or event.GetEventObject().Refresh() after changing the value of the Toggle doesn't seem to change anything.更改 Toggle 的值后调用event.GetEventObject().Update()event.GetEventObject().Refresh()似乎没有任何改变。

EDIT :编辑

If I use a Thread instead of Process , it works correctly, but I chose Process over Thread because I want the ability to kill it cleanly whenever I need to.如果我使用Thread而不是Process ,它可以正常工作,但我选择Process不是Thread因为我希望能够在需要时干净地杀死它。

Python version: 3.7 Python版本: 3.7

WxPython version: 4.0.1 WxPython 版本: 4.0.1

You must remember, that the your update_toggle runs in a new process.您必须记住,您的 update_toggle 在新进程中运行。 Simply put, it has got a copy of data, so if you call event.GetEventObject().SetValue(False) it happens in the new process, and the original one with the Window and Button won't know.简单地说,它有一份数据的副本,所以如果你调用 event.GetEventObject().SetValue(False) 它发生在新的进程中,而原来的带有 Window 和 Button 的进程不会知道。

You must somehow pass a message from the new process to the original.您必须以某种方式将消息从新进程传递到原始进程。 I would suggest that the first thing you try is:我建议您尝试的第一件事是:

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

This will block, but at least you will see if the "update_toggle_process" has finished and if this approach works.这会阻塞,但至少您会看到“update_toggle_process”是否已完成以及此方法是否有效。 After that, there are a few possibilities:之后,有几种可能:

  • Set up a times and periodically call self.update_toggle_process.is_alive()设置时间并定期调用 self.update_toggle_process.is_alive()
  • Create a new thread, call the update_toggle_process.start() from it, and also join().创建一个新线程,从中调用 update_toggle_process.start() 和 join()。 When finished, tell the main thread to toggle the button (remember that you may only manipulate the UI from the main thread in wx)完成后,告诉主线程切换按钮(请记住,您只能在 wx 中从主线程操作 UI)
  • Maybe you do not need a new process, a thread will be enough也许你不需要一个新进程,一个线程就足够了
  • Look at the multiprocessing IPC查看多处理 IPC

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何通过命令行切换过程状态? - How to toggle process state via command line? 完成过程后如何杀死终端 - How to kill a terminal after completion of process 脚本完成后如何让键盘恢复原来的state? - How to return the keyboard to its original state after the completion of the script? 当另一个切换按钮处于活动状态时,Kivy 更改切换按钮的状态 - Kivy Changing State of Toggle Button When Another Toggle Button Is Active Kivy:使用切换按钮更改另一个切换按钮的状态 - Kivy: Use a toggle button to change the state of another toggle button Python Bokeh:如何在子例程中更新“切换”按钮-在主菜单中定义 - Python Bokeh: How to update a Toggle button - defined in the main - in a subroutine Python-子窗口上的Tkinter退出按钮及其对切换按钮状态的影响 - Python - Tkinter exit button on a child window and how it affects a toggle button state 单击切换按钮后如何执行 django 或 SQL 查询? - How to execute a django or SQL query after clicking the toggle button? 设置工具栏按钮切换状态wxpython - Set toolbar button toggle state wxpython 单击时中断 Kivy 切换按钮状态更改 - Interrupting Kivy Toggle Button State Change on Click
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM