wxPython - 事件處理



與以順序方式執行的控制檯模式應用程式不同,基於 GUI 的應用程式是事件驅動的。函式或方法響應使用者操作(例如單擊按鈕、從集合中選擇專案或滑鼠單擊等,稱為事件)而執行。

與應用程式執行時發生的事件相關的資料儲存為從wx.Event派生的子類的物件。顯示控制元件(如按鈕)是特定型別事件的源,並生成與其關聯的 Event 類物件。例如,單擊按鈕會發出 wx.CommandEvent。此事件資料被分派到程式中的事件處理程式方法。wxPython 具有許多預定義的事件繫結器。事件繫結器封裝了特定視窗小部件(控制元件)、其關聯的事件型別和事件處理程式方法之間的關係。

例如,要在按鈕的單擊事件上呼叫程式的OnClick() 方法,需要以下語句:

self.b1.Bind(EVT_BUTTON, OnClick)

Bind() 方法由所有顯示物件從 wx.EvtHandler 類繼承。此處的 EVT_.BUTTON 是繫結器,它將按鈕單擊事件與 OnClick() 方法關聯。

示例

在以下示例中,由拖動頂級視窗(在本例中為 wx.Frame 物件)引起的 MoveEvent 與OnMove() 方法使用 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()   

以上程式碼產生以下輸出:

Move Event

當前視窗位置 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 生成命令事件。命令事件可以傳播到視窗或視窗,這些視窗在類層次結構中位於源視窗的上方。

示例

以下是一個簡單的事件傳播示例。完整程式碼如下:

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 類進行傳輸。以上程式碼產生以下輸出:

Event Handling Output

Button received click event. Propagated to Panel class. 
Panel received click event. Propagated to Frame class. 
Click event received by frame class.
廣告

© . All rights reserved.