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”。

上一篇:ImportError: No module named uinput
下一篇:QGroupBox 显示边框 圆角边框 linux环境

发表评论

最新留言

能坚持,总会有不一样的收获!
[***.219.124.196]2025年04月08日 13时22分57秒