python - 流程完成后如何更新切换按钮的状态?
问题描述
我想在单击(打开)切换按钮时执行任务并在任务完成后将其关闭,我在新进程中执行任务,因为我不希望它阻塞 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()
event.GetEventObject().Update()
更改 Toggle 的值或更改后的调用event.GetEventObject().Refresh()
似乎没有改变任何东西。
编辑:
如果我使用 aThread
而不是Process
,它可以正常工作,但我选择Process
了 over ,Thread
因为我希望能够在需要时干净地杀死它。
Python版本: 3.7
WxPython 版本: 4.0.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
推荐阅读
- javascript - 如何在Jquery中将文本附加到左侧而不是添加到右侧
- sql - 如何选择一组预定义的值及其计数?
- alteryx - 如何将 Alteryx .yxzp 文件解包到较低版本
- wpf - 如何使用 MVVM 模型从 WPF 中的 CheckListBox 中绑定选中/选定项目(我正在使用“WPFToolkit.Extended.dll”来获取 CheckListBox 控件)
- c# - 如何在 C# 的同一个构造函数中初始化同一个类
- terraform - 使用 terraform 在 for_each 嵌套资源中循环
- php - 使用 WordPress 插件中的目录在 URL 上生成自定义输出
- ios - 如何在 UIViewControllerRepresentable Struct 中创建 UIBarButtonItem?
- javascript - 如何在 keyCode 导航的输入中设置自动焦点?
- angular - 角度异步验证器错误未显示