- wxPython 教程
- wxPython - 首頁
- wxPython - 簡介
- wxPython - 環境
- wxPython - Hello World
- wxPython - GUI 構建工具
- wxPython - 主要類
- wxPython - 事件處理
- wxPython - 佈局管理
- wxPython - 按鈕
- wxPython - 可停靠視窗
- 多文件介面
- wxPython - 繪圖 API
- wxPython - 拖放
- wxPython 資源
- wxPython - 快速指南
- wxPython - 有用資源
- wxPython - 討論
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()
以上程式碼產生以下輸出:
當前視窗位置 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 類進行傳輸。以上程式碼產生以下輸出:
Button received click event. Propagated to Panel class. Panel received click event. Propagated to Frame class. Click event received by frame class.