
wxPython:事件、键盘监听
发布日期:2021-05-08 01:20:56
浏览次数:27
分类:精选文章
本文共 5269 字,大约阅读时间需要 17 分钟。
代码一
代码展示
import wxclass MyFrame(wx.Frame): def __init__(self, parent, id=wx.ID_ANY, title='', pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE, name='MyFrame'): super(MyFrame, self).__init__(parent, id, title, pos, size, style, name) self.panel = wx.Panel(self) self.btn1 = wx.Button(self.panel, label='Button 01') self.btn2 = wx.Button(self.panel, label='Button 02') sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(self.btn1, 0, wx.ALL, 0) sizer.Add(self.btn2, 0, wx.ALL, 0) self.panel.SetSizer(sizer) self.Bind(wx.EVT_BUTTON, self.onButton, self.btn1) self.Bind(wx.EVT_BUTTON, lambda event: self.btn1.Enable(not self.btn1.Enabled), self.btn2) def onButton(self, event): event_id = event.GetId() event_obj = event.GetEventObject() print("ID=%s" % event_id) print("Obj=%s" % event_obj)
基本概念
- 事件句柄:即事件的触发函数。
- 窗口层次:在 wxPython 中,所有控件都是窗口,包括 Frame、Panel、Boxer 和 Button 等。
- 事件 Binder 对象:如 wx.EVT_BUTTON。
- 事件对象:作为事件句柄的第一个参数,可提取事件信息。
事件传播
事件首先在 Frame 上触发,然后逐级传递到 Panel 和 Button。这种机制使得事件能够在多个级别上处理。
两种事件
- Command event:支持传播。
- Event:不支持传播。
代码示例
ID_BUTTON1 = wx.NewId()ID_BUTTON2 = wx.NewId()class MyApp(wx.App): def OnInit(self): self.frame = MyFrame(None, title='Test') self.SetTopWindow(self.frame) self.frame.Show() self.Bind(wx.EVT_BUTTON, self.onButtonApp) return True def onButtonApp(self, event): event_id = event.GetId() if event_id == ID_BUTTON1: print("BUTTON ONE event reached the App")class MyFrame(wx.Frame): def __init__(self, parent, id=wx.ID_ANY, title='', pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE, name='MyFrame'): super(MyFrame, self).__init__(parent, id, title, pos, size, style, name) self.panel = MyPanel(self) self.btn1 = wx.Button(self.panel, id=ID_BUTTON1, label='Command Event') self.btn2 = wx.Button(self.panel, id=ID_BUTTON2, label='Event') sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(self.btn1, 0, wx.ALL, 10) sizer.Add(self.btn2, 0, wx.ALL, 10) self.panel.SetSizer(sizer) self.Bind(wx.EVT_BUTTON, self.onButtonFrame) def onButtonFrame(self, event): event_id = event.GetId() if event_id == ID_BUTTON1: print("BUTTON ONE event reached the Frame") event.Skip() elif event_id == ID_BUTTON2: print("BUTTON TWO event reached the Frame")class MyPanel(wx.Panel): def __init__(self, parent): super(MyPanel, self).__init__(parent) self.Bind(wx.EVT_BUTTON, self.onButtonPanel) def onButtonPanel(self, event): event_id = event.GetId() if event_id == ID_BUTTON1: print("BUTTON ONE event reached the Panel") event.Skip() elif event_id == ID_BUTTON2: print("BUTTON TWO event reached the Panel")
如何工作?
事件通过层级传播机制从 Frame 到 Button 处理,支持传播的事件可继续向上处理。
键盘监听
import wxclass MyFrame(wx.Frame): def __init__(self, parent, id=wx.ID_ANY, title='', pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE, name='MyFrame'): super(MyFrame, self).__init__(parent, id, title, pos, size, style, name) self.panel = wx.Panel(self) self.txtCtrl = wx.TextCtrl(self.panel, style=wx.TE_MULTILINE) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(self.txtCtrl, 1, wx.EXPAND) self.panel.SetSizer(sizer) self.CreateStatusBar() self.txtCtrl.Bind(wx.EVT_KEY_DOWN, self.onKeyDown) self.txtCtrl.Bind(wx.EVT_CHAR, self.onChar) self.txtCtrl.Bind(wx.EVT_KEY_UP, self.onKeyUp) def onKeyDown(self, event): print('onKeyDown called') key_code = event.GetKeyCode() raw_code = event.GetRawKeyCode() modifiers = event.GetModifiers() msg = "key:%d,raw:%d,modifier:%d" % (key_code, raw_code, modifiers) self.PushStatusText("KeyDown: " + msg) event.Skip() def onChar(self, event): print('onChar called') key_code = event.GetKeyCode() raw_code = event.GetRawKeyCode() modifiers = event.GetModifiers() msg = 'key:%d,raw:%d,modifier:%d' % (key_code, raw_code, modifiers) if modifiers & wx.MOD_SHIFT: wx.Bell() elif chr(key_code) in 'aeiou': self.txtCtrl.AppendText('?') else: event.Skip() def onKeyUp(self, event): print('onKeyUp called') event.Skip()
更新你的 App
添加菜单栏
在 MyFrame 的 init 方法中添加:
menuBar = wx.MenuBar()editMenu = wx.Menu()editMenu.Append(wx.ID_COPY, "Copy\tCtrl+C")editMenu.Append(wx.ID_CUT, "CUT\tCtrl+X")editMenu.Append(wx.ITEM_CHECK, "Selection Made?", kind=wx.ITEM_CHECK)menuBar.Append(editMenu, "Edit")self.SetMenuBar(menuBar)self.Bind(wx.EVT_UPDATE_UI, self.onUpdateEditMenu)
注册快捷键方法
快捷键格式为:“名称\t快捷键”,如“Copy\tCtrl+X”。
发表评论
最新留言
能坚持,总会有不一样的收获!
[***.219.124.196]2025年04月08日 13时22分57秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
MySQL数据库与python交互
2019-03-06
python如何对字符串进行html转义与反转义?
2019-03-06
开发小白也毫无压力的hexo静态博客建站全攻略 - 躺坑后亲诉心路历程
2019-03-06
golang基础--类型与变量
2019-03-06
.NetCore外国一些高质量博客分享
2019-03-06
解决WebRTC中不同的浏览器之间适配的问题
2019-03-06
深入理解JavaScript函数
2019-03-06
【spring源码系列】之【xml解析】
2019-03-06
(在模仿中精进数据可视化07)星球研究所大坝分布可视化
2019-03-06
(数据科学学习手札02)Python与R在循环语句与条件语句上的异同
2019-03-06
(数据科学学习手札27)sklearn数据集分割方法汇总
2019-03-06
(数据科学学习手札40)tensorflow实现LSTM时间序列预测
2019-03-06
[整理] 哪些集合类是线程安全的?(Java)
2019-03-06
8 个警示和学习的 5 个阶段
2019-03-06
c# 图片带水纹波动
2019-03-06
H5 贪吃蛇源码
2019-03-06
从零开始学安全(十六)● Linux vim命令
2019-03-06
从零开始学安全(三十四)●百度杯 ctf比赛 九月场 sqli
2019-03-06
3389连接痕迹清除
2019-03-06