multithreading - 有没有办法向 wxApp 发送事件?
问题描述
我将 wxPython 用于 GUI,并且我有一个与某些 I/O 交互的不同线程。当线程从 I/O 设备接收到事件时,有没有办法更新 GUI 以显示 I/O 状态?更清楚一点:IOthread 每 3 秒询问一次停车栏是向上还是向下,我希望 GUI 在向下或向上时显示红色 LED 或绿色 LED。所以基本上我需要将 IOthread 接收到的信息传达给在主线程中运行的 GUI
解决方案
您可以看一下,pubsub
但是当您使用带有线程的 wxPython 时,使用用户定义的event
.
这个改编的代码只是在 True 和 False 之间交替,显然你会改变它并且只发布事件,如果它改变了。
from threading import Thread
import wx
import time
import wx.lib.newevent
progress_event, EVT_PROGRESS_EVENT = wx.lib.newevent.NewEvent()
class WorkThread(Thread):
def __init__(self,parent_target):
"""Init Worker Thread Class."""
Thread.__init__(self)
self.target = parent_target
self.stop_work_thread = 0
self.start() # start the thread
def run(self):
curr_loop = True
while True:
if self.stop_work_thread == 1: # Exit
break
time.sleep(1)
if self.stop_work_thread == 2: # Paused
continue
curr_loop = not curr_loop
evt = progress_event(active=curr_loop,name=self.name)
#Send back current bar position up True, Down False
try:
wx.PostEvent(self.target, evt)
except: # The parent frame has probably been destroyed
self.stop()
return
def stop(self):
self.stop_work_thread = 1
def pause(self):
if self.stop_work_thread == 2:
self.stop_work_thread = 0
self.target.pause_btn.SetLabel('Pause')
else:
self.stop_work_thread = 2
self.target.pause_btn.SetLabel('Paused')
class Progress(wx.Frame):
def __init__(self, parent, title):
super(Progress, self).__init__(parent, title = title,size = (500,300))
left_sizer = wx.BoxSizer(wx.VERTICAL)
middle_sizer = wx.BoxSizer(wx.HORIZONTAL)
self.panel = wx.Panel(self)
self.start_btn = wx.Button(self.panel, label="Start")
self.stop_btn =wx.Button(self.panel, label="Stop")
self.pause_btn =wx.Button(self.panel, label="Pause")
self.quit_btn =wx.Button(self.panel, label="Quit")
self.logger = wx.TextCtrl(self.panel, size=(200,200), style=wx.TE_MULTILINE | wx.TE_READONLY)
self.stop_btn.Disable()
self.pause_btn.Disable()
left_sizer.Add(self.start_btn,0,wx.EXPAND)
left_sizer.Add(self.stop_btn,0,wx.EXPAND)
left_sizer.Add(self.pause_btn,0,wx.EXPAND)
left_sizer.Add(self.quit_btn,0,wx.EXPAND)
middle_sizer.Add(self.logger,0,wx.EXPAND)
self.mainsizer = wx.BoxSizer(wx.HORIZONTAL)
self.mainsizer.Add(left_sizer)
self.mainsizer.Add(middle_sizer)
self.panel.SetSizer(self.mainsizer)
self.Layout()
self.start_btn.Bind(wx.EVT_BUTTON, self.onStart)
self.stop_btn.Bind(wx.EVT_BUTTON, self.onCancel)
self.pause_btn.Bind(wx.EVT_BUTTON, self.onPause)
self.quit_btn.Bind(wx.EVT_BUTTON, self.onExit)
#Bind to the progress event issued by the thread
self.Bind(EVT_PROGRESS_EVENT, self.OnActive)
self.Bind(wx.EVT_CLOSE, self.onExit)
def OnActive(self, event):
if not self.work.is_alive():
return
active = event.active
ident = event.name
if active:
self.logger.Clear()
self.logger.SetBackgroundColour("green")
self.logger.write('\n\n\n\n\n\t\tBar is Up')
else:
self.logger.Clear()
self.logger.SetBackgroundColour("red")
self.logger.write('\n\n\n\n\n\t\tBar is Down')
def onStart(self, event):
self.start_btn.Disable()
self.work = WorkThread(parent_target=self)
self.pause_btn.Enable()
self.stop_btn.Enable()
def onPause(self, event):
if self.work.is_alive():
self.work.pause() # Pause the thread
def onCancel(self, event):
"""Cancel thread process"""
try:
self.work.stop()
self.work.join()
except:
pass
self.onFinish()
def onFinish(self):
"""thread process finished - clean up"""
self.start_btn.Enable()
self.stop_btn.Disable()
self.pause_btn.Disable()
self.pause_btn.SetLabel("Pause")
self.logger.Clear()
self.logger.SetBackgroundColour("white")
def onExit(self, event):
self.onCancel(None)
self.onFinish()
self.Destroy()
app = wx.App()
frame = Progress(None,'Bar Up/Down Display')
frame.Show()
app.MainLoop()
推荐阅读
- java - 我想将一个字符串添加到一个字符串数组中
- kubernetes - kube-system:Pod 警告 FailedScheduling default-scheduler 没有可用于调度 Pod 的节点
- c++ - 使用 C++ 动态分配 /dev/ttyUSB*
- node.js - Node.js - 使用 Google Cloud Vision API 从 PDF 文件中提取文本的问题
- java - Java Spoon API Object.hashCode()
- selenium - 使用 selenium 独立服务和 chrome 运行 wdio.conf.js 时获取 selenium 页面的 html 输出错误
- reactjs - 如何向 createMaterialTopTabNavigator(React Navigator)添加后退按钮?
- angular - 如何以角度创建弹出窗口
- r - `sym()` 对 tidyeval 有什么作用?
- r - R 安装以前的版本包 NAMESPACE 文件丢失