一個簡單的例子python
下面咱們將以一個 move envet 事件爲例子。當咱們一個窗口到一個新的位置的時候 ,就會產生一個 move envet 事件,其類型是 wx.MoveEvent,對應的 Binder 是 wx.EVT_MOVE。編程
import wxapp
class MoveEvent(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(250, 180))ide
wx.StaticText(self, -1, ‘x:’, (10,10))
wx.StaticText(self, -1, ‘y:’, (10,30))
self.st1 = wx.StaticText(self, -1, 」, (30, 10))
self.st2 = wx.StaticText(self, -1, 」, (30, 30))wordpress
self.Bind(wx.EVT_MOVE, self.OnMove)函數
self.Centre()
self.Show(True)oop
def OnMove(self, event):
x, y = event.GetPosition()
self.st1.SetLabel(str(x))
self.st2.SetLabel(str(y))post
app = wx.App()
MoveEvent(None, -1, ‘move event’)
app.MainLoop()ui
上面的例子將顯示窗口的當前位置。google
將 wx.EVT_MOVE 事件綁定到 OnMove() 方法上。
參數 event 是指定事件類型的對象,在咱們的例子中,它是 wx.MoveEvent 對象。wx.MoveEvent 是 wx.Frame 的 widget,咱們能夠調用 GetPosition() 來取得當前窗口的位置。
事件綁定
經過三步來進行事件的綁定:
經過調用 Bind() 方法來綁定事件,下面是其參數:
注意: Bind() 是定義於類 EvtHandler 中的方法,而 wx.Window 是它的子類。
若是想對事件進行解綁,可使用 Unbind(),它跟 Bind() 有着相同的參數。
攔截事件
有時,咱們須要中止處理某個事件,這就要用到方法 Veto()。
import wx
class Veto(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(250, 200))
self.Bind(wx.EVT_CLOSE, self.OnClose)
self.Centre()
self.Show(True)
def OnClose(self, event):
dial = wx.MessageDialog(None, ‘Are you sure to quit?’, ‘Question’,
wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
ret = dial.ShowModal()
if ret == wx.ID_YES:
self.Destroy()
else:
event.Veto()
app = wx.App()
Veto(None, -1, ‘Veto’)
app.MainLoop()
在上面的例子中,咱們處理了一個 wx.CloseEvent 事件────當窗口關閉時就會觸發。在某些應用程序裏,咱們但願阻止關閉窗口。
當觸發關閉事件,咱們將顯示一個消息對話框。
根據返回值,咱們決定關閉窗口仍是攔截關閉事件。注意:咱們必須經過調用 Destory() 方法來關閉窗口,來中止最終的事件循環。
事件傳送(Event propagation)
事件大致能夠分兩類:普通事件(Basic events)和命令事件(Command events),它們的區別在於傳送的不一樣。事件傳送是指事件從一個子 widgets 傳遞到父 widgets 或者更上一級的父 widgets。普通事件沒有傳送,而命令事件則有。舉一個例子,wx.CloseEvent 是一個普通事件,它不會將關閉事件傳遞到父一級的 widgets。
普通,當一個事件處理器(Event handler)捕獲一個事件,它會阻止這個事件繼續向上一級傳送。要想繼續事件的傳遞,必須使用 Skip() 方法。
import wx
class MyPanel(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent, id)
self.Bind(wx.EVT_BUTTON, self.OnClicked)
def OnClicked(self, event):
print ‘event reached panel class’
event.Skip()
class MyButton(wx.Button):
def __init__(self, parent, id, label, pos):
wx.Button.__init__(self, parent, id, label, pos)
self.Bind(wx.EVT_BUTTON, self.OnClicked)
def OnClicked(self, event):
print ‘event reached button class’
event.Skip()
class Propagate(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(250, 150))
panel = MyPanel(self, -1)
MyButton(panel, -1, ‘Ok’, (15, 15))
self.Bind(wx.EVT_BUTTON, self.OnClicked)
self.Centre()
self.Show(True)
def OnClicked(self, event):
print ‘event reached frame class’
event.Skip()
app = wx.App()
Propagate(None, -1, ‘Propagate’)
app.MainLoop()
在上面的例子中,咱們在窗口上放置一個面板,在面板上又放置一個按鈕。
當咱們單擊按鈕,將會顯示上面的內容。這是由於單擊事件從按鈕一直傳遞到面板和窗口。有興趣的話,能夠註釋掉 Skip(),看看有什麼不一樣的事情發生。
窗口識別碼(Window identifiers)
窗口識別碼是一個惟一的整數,用於在事件系統中對不一樣窗口的識別。能夠經過3個方法建立窗口 id’s:
每個 widget 都有一個 id 參數,它是事件系統中的惟一識別碼。
若是咱們設置 id 參數爲 -1 或者 wx.ID_ANY,表示讓 wxPython 自動建立 id。自動建立的 id’s 老是負數來的,而用戶定義的 id’s 必須老是正數。
import wx
class AuIds(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(170, 100))
panel = wx.Panel(self, -1)
exit = wx.Button(panel, -1, ‘Exit’, (10, 10))
self.Bind(wx.EVT_BUTTON, self.OnExit, id=exit.GetId())
self.Centre()
self.Show(True)
def OnExit(self, event):
self.Close()
app = wx.App()
AuIds(None, -1, 」)
app.MainLoop()
在上面的例子中,咱們不用關心實際的 id 值。
經過調用 GetId() 方法取得自動建立的 id 的值。
標準識別碼(Standar identifiers)也能夠隨時使用,並且在某此平臺上,它提供了一些標準圖標和行爲。
import wx
class Identifiers(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(200, 150))
panel = wx.Panel(self, -1)
grid = wx.GridSizer(3, 2)
grid.AddMany([(wx.Button(panel, wx.ID_CANCEL), 0, wx.TOP | wx.LEFT, 9),
(wx.Button(panel, wx.ID_DELETE), 0, wx.TOP, 9),
(wx.Button(panel, wx.ID_SAVE), 0, wx.LEFT, 9),
(wx.Button(panel, wx.ID_EXIT)),
(wx.Button(panel, wx.ID_STOP), 0, wx.LEFT, 9),
(wx.Button(panel, wx.ID_NEW))])
self.Bind(wx.EVT_BUTTON, self.OnQuit, id=wx.ID_EXIT)
panel.SetSizer(grid)
self.Centre()
self.Show(True)
def OnQuit(self, event):
self.Close()
app = wx.App()
Identifiers(None, -1, 」)
app.MainLoop()
Miscellaneous events
Focus 事件
所謂焦點(Focus)是程序中指當前被選擇的 widget。當一個文本 widget 得到焦點時,咱們能夠從鍵盤輸入字符或者從粘貼板中粘貼文本。
有2種 Focus 事件 Handlers:wx.EVT_SET_FOCUS,當一個 widget 得到焦點的時候來觸發;wx.EVT_KILL_FOCUS,當 widget 失去焦點的時候會觸發。焦點的改變可能經過鼠標的單擊或者鍵盤按鍵,一般是 Tab/Shit+Tab。
import wx
class MyWindow(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, -1)
self.color = ‘#b3b3b3′
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Bind(wx.EVT_SIZE, self.OnSize)
self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)
self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
def OnPaint(self, event):
dc = wx.PaintDC(self)
dc.SetPen(wx.Pen(self.color))
x, y = self.GetSize()
dc.DrawRectangle(0, 0, x, y)
def OnSize(self, event):
self.Refresh()
def OnSetFocus(self, event):
self.color = ‘#0099f7′
self.Refresh()
def OnKillFocus(self, event):
self.color = ‘#b3b3b3′
self.Refresh()
class FocusEvent(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(350, 250))
grid = wx.GridSizer(2, 2, 10, 10)
grid.AddMany([(MyWindow(self), 1, wx.EXPAND|wx.TOP|wx.LEFT,9),
(MyWindow(self), 1, wx.EXPAND|wx.TOP|wx.RIGHT, 9),
(MyWindow(self), 1, wx.EXPAND|wx.BOTTOM|wx.LEFT, 9),
(MyWindow(self), 1, wx.EXPAND|wx.BOTTOM|wx.RIGHT, 9)])
self.SetSizer(grid)
self.Centre()
self.Show(True)
app = wx.App()
FocusEvent(None, -1, ‘focus event’)
app.MainLoop()
ScrollEvent
當咱們按下內建生成的滾動條的時候(使用 SetScrollbar() 來激活內建的滾動條),會觸發 wx.ScrollWinEvent 事件。對於非內建的滾動條,其事件類型爲 wx.ScrollEvent。
import wx
class ScrollWinEvent(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title)
panel = wx.Panel(self, -1)
self.st = wx.StaticText(panel, -1, ’0′, (30,0))
panel.Bind(wx.EVT_SCROLLWIN, self.OnScroll)
panel.SetScrollbar(wx.VERTICAL, 0, 6, 50);
self.Centre()
self.Show(True)
def OnScroll(self, evt):
y = evt.GetPosition()
self.st.SetLabel(str(y))
app = wx.App()
ScrollWinEvent(None, -1, ‘scrollwinevent.py’)
app.MainLoop()
SizeEvent
當咱們改變窗口大小的時候,會觸發 wx.SizeEvent 事件。
import wx
class SizeEvent(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title)
self.Bind(wx.EVT_SIZE, self.OnSize)
self.Centre()
self.Show(True)
def OnSize(self, event):
self.SetTitle(str(event.GetSize()))
app = wx.App()
SizeEvent(None, 1, ‘sizeevent.py’)
app.MainLoop()
在上面的例子中,咱們在標題欄上顯示窗口的大小。
經過調用事件對象的 GetSize() 方法取得當前窗口的大小。
PaintEvent
當一個窗口被重畫的時候,會觸發 PaintEvent 事件。當窗口大小被改變或者最大化窗口,又或者經過編程,均可以令到窗口重畫。例如,咱們調用 SetLabel() 來改變 wx.StaticText。注意,最小化窗口的時候,不會觸發 PaintEvent 事件。
import wx
class PaintEvent(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title)
self.count = 0
self.Bind(wx.EVT_PAINT, self.OnPaint)
self.Centre()
self.Show(True)
def OnPaint(self, event):
self.count = self.count + 1
print self.count
app = wx.App()
PaintEvent(None, -1, ‘paintevent.py’)
app.MainLoop()
KeyEvent
當咱們經過鍵盤按鍵時,會觸發 wx.KeyEvent 事件。事件會傳遞到當前得到焦點的 widget。 wx.KeyEvent 事件有3種 hanlders:
在下面的例子中,當按下 Esc 鍵時會關閉應用程序。
import wx
class KeyEvent(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title)
panel = wx.Panel(self, -1)
panel.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
panel.SetFocus()
self.Centre()
self.Show(True)
def OnKeyDown(self, event):
keycode = event.GetKeyCode()
if keycode == wx.WXK_ESCAPE:
ret = wx.MessageBox(‘Are you sure to quit?’, ‘Question’,
wx.YES_NO | wx.NO_DEFAULT, self)
if ret == wx.YES:
self.Close()
event.Skip()
app = wx.App()
KeyEvent(None, -1, ‘keyevent.py’)
app.MainLoop()