wxPython - 事件处理

  • 简述

    与以顺序方式执行的控制台模式应用程序不同,基于 GUI 的应用程序是事件驱动的。函数或方法响应用户的操作(如单击按钮、从集合中选择项目或鼠标单击等)执行,称为事件。
    与在应用程序运行时发生的事件有关的数据存储为派生自的子类的对象wx.Event. 显示控件(例如 Button)是特定类型的事件源,并生成与其关联的 Event 类的对象。例如,单击按钮会发出 wx.CommandEvent。该事件数据被分派给程序中的事件处理方法。wxPython 有许多预定义的事件绑定器。一个Event binder封装特定小部件(控件)、其关联的事件类型和事件处理程序方法之间的关系。
    例如,调用OnClick() method在按钮的单击事件上的程序中,需要以下语句 -
    
    self.b1.Bind(EVT_BUTTON, OnClick)
    
    Bind() method由 wx.EvtHandler 类的所有显示对象继承。这里的 EVT_.BUTTON 是绑定器,它将按钮单击事件与 OnClick() 方法相关联。
  • 例子

    在以下示例中,由拖动顶层窗口(在本例中为 wx.Frame 对象)引起的 MoveEvent 连接到OnMove() method使用 wx.EVT_MOVE 活页夹。代码显示一个窗口。如果使用鼠标移动它,它的瞬时坐标会显示在控制台上。
    
    import wx
      
    class Example(wx.Frame): 
                
       def __init__(self, *args, **kw): 
          super(Example, self).__init__(*args, **kw)  
          self.InitUI() 
               
       def InitUI(self): 
          self.Bind(wx.EVT_MOVE, self.OnMove) 
          self.SetSize((250, 180)) 
          self.SetTitle('Move event') 
          self.Centre() 
          self.Show(True)
                       
       def OnMove(self, e): 
          x, y = e.GetPosition() 
          print "current window position x = ",x," y= ",y 
             
    ex = wx.App() 
    Example(None) 
    ex.MainLoop()   
    
    上面的代码产生以下输出 -
    移动事件
    当前窗口位置 x = 562 y = 309
    当前窗口位置 x = 562 y = 309
    当前窗口位置 x = 326 y = 304
    当前窗口位置 x = 384 y = 240
    当前窗口位置 x = 173 y = 408
    当前窗口位置 x = 226 y = 30
    当前窗口位置 x = 481 y = 80
    下表列出了一些从 wx.Event 继承的子类 -
    序列号 事件和描述
    1
    wxKeyEvent
    按下或释放键时发生
    2
    wxPaintEvent
    每当需要重绘窗口内容时生成
    3
    wxMouseEvent
    包含有关由于鼠标活动(例如按下或拖动鼠标按钮)引起的任何事件的数据
    4
    wxScrollEvent
    与 wxScrollbar 和 wxSlider 等可滚动控件相关联
    5
    wxCommandEvent
    包含源自许多小部件(如按钮、对话框、剪贴板等)的事件数据。
    6
    wxMenuEvent
    不同的菜单相关事件,不包括菜单命令按钮单击
    7
    wxColourPickerEvent
    wxColourPickerCtrl 生成的事件
    8
    wxDirFilePickerEvent
    FileDialog 和 DirDialog 生成的事件
    wxPython 中的事件有两种类型。基本事件和命令事件。基本事件保持在它起源的窗口的本地。大多数 wxWidgets 生成命令事件。一种command event可以传播到类层次结构中源窗口之上的一个或多个窗口。
  • 例子

    以下是事件传播的一个简单示例。完整的代码是 -
    
    import wx
      
    class MyPanel(wx.Panel): 
         
       def __init__(self, parent): 
          super(MyPanel, self).__init__(parent)
                    
          b = wx.Button(self, label = 'Btn', pos = (100,100)) 
          b.Bind(wx.EVT_BUTTON, self.btnclk) 
          self.Bind(wx.EVT_BUTTON, self.OnButtonClicked) 
                    
       def OnButtonClicked(self, e): 
             
          print 'Panel received click event. propagated to Frame class' 
          e.Skip()  
                    
       def btnclk(self,e): 
          print "Button received click event. propagated to Panel class" 
          e.Skip()
                    
    class Example(wx.Frame):
       def __init__(self,parent): 
          super(Example, self).__init__(parent)  
             
          self.InitUI() 
       def InitUI(self):
            
          mpnl = MyPanel(self) 
          self.Bind(wx.EVT_BUTTON, self.OnButtonClicked)
                    
          self.SetTitle('Event propagation demo') 
          self.Centre() 
          self.Show(True)
                    
       def OnButtonClicked(self, e): 
             
          print 'click event received by frame class' 
          e.Skip()
                    
    ex = wx.App() 
    Example(None) 
    ex.MainLoop()
    
    在上面的代码中,有两个类。MyPanel, wx.Panel 子类和 Example, wx.Frame 子类,它是程序的顶级窗口。一个按钮被放置在面板中。
    此 Button 对象绑定到事件处理程序 btnclk() ,该事件处理程序将其传播到父类(在本例中为 MyPanel)。按钮单击生成一个CommandEvent可以通过 Skip() 方法传播到其父级。
    MyPanel 类对象还将接收到的事件绑定到另一个处理程序 OnButtonClicked()。该函数依次传递给它的父类,即 Example 类。上面的代码产生以下输出 -
    事件处理输出
    
    Button received click event. Propagated to Panel class. 
    Panel received click event. Propagated to Frame class. 
    Click event received by frame class.