最近搗鼓Python,也就天然搗鼓上了wxPython。我曾經用過Qt和Gtk+寫GUI,但幾乎全部的Python書都告訴我說最好用的是wxPython,我沒有嘗試PyQt和PyGtk就開始研究wxPython了。在Qt和Gtk+之間我更喜歡Qt,由於它跨平臺作得很好,並且商業化也不錯。但wxWidget給人的感受就徹底不一樣了。小程序
若是說wxWidgets相對於Qt有什麼優點的話,大概就只有體積較小了。從開發效率上看,若是不和Python組合真的比不上Qt;從商業支持上看wxWidgets根本沒有。不過和Python組合以後,開發效率大大提升,雖然用來作很正式的商業軟件並不合適,但寫寫小程序仍是很方便的。函數
如今切入正題,wxWidgets是一個事件驅動的體系,對於觸發的事件,須要給它掛上相應的事件處理函數。在Python中這個函數的形式是這樣的:code
wx.Frame.Bind(self, event, handler, source=None, id=-1, id2=-1)
在通常使用時,咱們基本上只會給定event、handler和source,event是事件的名稱,handler是處理函數,source是事件的發生者,好比一個Button1被單擊而發生了EVT_BUTTON事件,若是咱們用self.OnButton1()來處理,會這麼寫:事件
self.Bind(wx.EVT_BUTTON, self.OnButton1, self.Button1)
這裏self是一個Frame(wxPython中的窗體這樣的東西),而Button1是放在這個Frame下面的一個Button,self.OnButton1就是事件處理函數。而wxPython定死了事件處理函數的形式:開發
def handler(self,event): ...
事件處理函數只能接受兩個參數,一個仍是self。至於event,一看就知道是那個發生的事件。但這樣就有一個問題了:若是我想批量建立一些按鈕或者菜單鍵(我想這種事情是很廣泛的),而且但願用同一個函數來處理它們,這個函數該怎樣辨別是哪一個按鈕觸發的事件呢?顯然咱們但願能多傳一些參數。Qt實現這一點很容易,但wxWidgets就顯得很棘手了。get
我並無用C++寫過wxWidgets的程序——確切地講是複製過一個example的,可是不知道是我英語太差沒能找到仍是真的沒有,我沒有在wxWidgets的入門指南中找到編譯指令,最後無法編譯它。所以我不知道這個限制是否是C++也有,可是Python能夠經過lambda來解決這個問題。如下的例子我用的是菜單。編譯
首先咱們建一個OnMenusClick函數:入門
def OnMenusClick(self, event, mark): ....
這個函數多接收一個mark,綁定的時候,就不是把OnMenusClick直接綁定上去,而是傳遞一個被lambda包裝過的函數。下面這個例子就會創建一堆Menu的按鍵,並給他們編號,OnMenusClick就能夠接收到它們的編號了:event
menu=wx.Menu() for i in range(0,N): btn=menu.Append(wx.NewId(), str(i)) self.Bind(wx.EVT_MENU, lambda evt, mark=i : self.OnMenusClick(evt,mark) ,btn )
完成了!是否是感受有點magic?關鍵在於這句lambda效率
lambda evt, mark=i : self.OnMenusClick(evt,mark)
這句實際上產生了只接收evt一個參數的函數,並將其傳遞給了self.OnMenusClick,這樣就可以實現給事件處理函數傳遞更多參數的目的了。