
- wxPython 教程
- wxPython - 首頁
- wxPython - 簡介
- wxPython - 環境配置
- wxPython - Hello World
- wxPython - GUI構建工具
- wxPython - 主要類
- wxPython - 事件處理
- wxPython - 佈局管理
- wxPython - 按鈕
- wxPython - 可停靠視窗
- 多文件介面
- wxPython - 繪圖API
- wxPython - 拖放操作
- wxPython 資源
- wxPython 快速指南
- wxPython - 有用資源
- wxPython - 討論
wxPython 快速指南
wxPython - 簡介
wxPython 是一個 Python 包裝器,用於流行的跨平臺 GUI 工具包 wxWidgets(用 C++編寫)。由 Robin Dunn 和 Harri Pasanen 開發,wxPython 實現為一個 Python 擴充套件模組。
就像 wxWidgets 一樣,wxPython 也是一個自由軟體。它可以從官方網站 http://wxpython.org 下載。許多作業系統的二進位制檔案和原始碼都可以在此網站下載。
wxPython API 中的主要模組包括一個核心模組。它包含wxObject 類,它是 API 中所有類的基類。控制元件模組包含 GUI 應用程式開發中使用的所有視窗部件。例如,wx.Button、wx.StaticText(類似於標籤)、wx.TextCtrl(可編輯文字控制元件)等。
wxPython API 有 GDI(圖形裝置介面)模組。它是一組用於在視窗部件上繪圖的類。字型、顏色、畫筆等類都是它的一部分。所有容器視窗類都在 Windows 模組中定義。
wxPython 的官方網站還託管 Project Phoenix——一個針對 Python 3.* 的 wxPython 新實現。它專注於提高速度、可維護性和可擴充套件性。該專案始於 2012 年,目前仍處於測試階段。
wxPython - 環境配置
Windows
Windows 作業系統(32 位和 64 位)的預構建二進位制檔案可在 http://www.wxpython.org/download.php 頁面上找到。最新的安裝程式版本如下:wxPython3.0-win32-3.0.2.0-py27.exe(適用於 32 位 Python 2.7) wxPython3.0-win64-3.0.2.0-py27.exe(適用於 64 位 Python 2.7)
wxPython 演示、示例和 wxWidgets 文件也可在同一頁面下載。
wxPython3.0-win32-docs-demos.exe
Linux
許多 Linux 發行版的 wxPython 二進位制檔案可以在其各自的儲存庫中找到。將需要使用相應的包管理器來下載和安裝。例如,在 Debian Linux 上,以下命令應該能夠安裝 wxPython。
sudo apt-get install python-wxgtk3.0
MacOS
MacOS 的預構建二進位制檔案(磁碟映像形式)可在官方網站的下載頁面上找到。
wxPython - Hello World
一個簡單的 GUI 應用程式,顯示 Hello World 訊息,使用以下步驟構建:
匯入 wx 模組。
定義 Application 類的物件。
建立一個頂級視窗作為 wx.Frame 類的物件。標題和大小引數在建構函式中給出。
雖然可以在 Frame 物件中新增其他控制元件,但無法管理它們的佈局。因此,將一個 Panel 物件放入 Frame 中。
新增一個 StaticText 物件,以在視窗內的所需位置顯示“Hello World”。
透過 show() 方法啟用框架視窗。
進入 Application 物件的主事件迴圈。
import wx app = wx.App() window = wx.Frame(None, title = "wxPython Frame", size = (300,200)) panel = wx.Panel(window) label = wx.StaticText(panel, label = "Hello World", pos = (100,50)) window.Show(True) app.MainLoop()
上述程式碼產生以下輸出:

wxFrame 物件是最常用的頂級視窗。它派生自wxWindow 類。框架是一個視窗,其大小和位置可以由使用者更改。它有一個標題欄和控制按鈕。如果需要,可以啟用選單欄、工具欄和狀態列等其他元件。wxFrame 視窗可以包含任何不是對話方塊或另一個框架的框架。
wxPython - GUI構建工具
透過手動編碼建立美觀的 GUI 可能很繁瑣。一個視覺化 GUI 設計器工具始終很方便。許多針對 wxPython 的 GUI 開發 IDE 都可用。以下是一些:
- wxFormBuilder
- wxDesigner
- wxGlade
- BoaConstructor
- gui2py
wxFormBuilder 是一個開源的、跨平臺的所見即所得 GUI 構建器,可以將 wxWidget GUI 設計轉換為 C++、Python、PHP 或 XML 格式。這裡簡要介紹了 wxFormBuilder 的使用方法。
首先,需要從 http://sourceforge.net/projects/wxformbuilder/ 下載並安裝最新版本的 wxFormBuilder。開啟應用程式後,中間會出現一個帶有空白灰色區域的新專案。
為專案命名,並選擇 Python 作為程式碼生成語言。這在物件屬性視窗中完成,如下圖所示:

然後從元件調色盤的“窗體”選項卡中選擇 Frame。

從“佈局”選項卡中新增一個垂直 wxBoxSizer。

在 Box 中新增必要的控制元件,並使用合適的標題。這裡添加了一個 StaticText(標籤)、兩個 TextCtrl 物件(文字框)和一個 wxButton 物件。框架如下圖所示:

在這三個控制元件上啟用 Expand 和 Stretch。在 wxButton 物件的物件屬性中,將函式 findsquare() 分配給 OnButtonClick 事件。

儲存專案並按 F8 生成已開發 GUI 的 Python 程式碼。將生成的程式碼檔案命名為 Demo.py
在可執行的 Python 指令碼中,匯入 demo.py 並定義 FindSquare() 函式。宣告 Application 物件並啟動主事件迴圈。以下是可執行程式碼:
import wx #import the newly created GUI file import demo class CalcFrame(demo.MyFrame1): def __init__(self,parent): demo.MyFrame1.__init__(self,parent) def FindSquare(self,event): num = int(self.m_textCtrl1.GetValue()) self.m_textCtrl2.SetValue (str(num*num)) app = wx.App(False) frame = CalcFrame(None) frame.Show(True) #start the applications app.MainLoop()
上述程式碼產生以下輸出:

wxPython - 主要類
原始 wxWidgets(用 C++編寫)是一個龐大的類庫。該庫中的 GUI 類使用 wxPython 模組移植到 Python,該模組試圖儘可能準確地映象原始 wxWidgets 庫。因此,wxPython 中的 wx.Frame 類與 C++ 版本中的 wxFrame 類的工作方式非常相似。
wxObject 是大多數類的基類。wxApp(在 wxPython 中為 wx.App)的物件表示應用程式本身。生成 GUI 後,應用程式透過 MainLoop() 方法進入事件迴圈。下圖描述了 wxPython 中最常用的 GUI 類的類層次結構。




序號 | 類和描述 |
---|---|
1 | wx.Frame
wx.Frame 類有一個沒有引數的預設建構函式。 |
2 | wx.Panel
wx.Panel 類通常放在 wxFrame 物件內。此類也繼承自 wxWindow 類。 |
3 | wx.StaticText
wx.StaticText 類物件呈現一個包含只讀文字的控制元件。因為它不會產生任何事件,所以它可以被稱為被動控制元件。 |
4 | TextCtrl
在 wxPython 中,wx.TextCtrl 類的物件用於此目的。它是一個可以顯示和編輯文字的控制元件。 |
5 | RadioButton & RadioBox
每個按鈕(wx.RadioButton 類的物件)在圓形按鈕旁邊都有一個文字標籤。wxPython API 還包含 wx.RadioBox 類。它的物件為該組提供邊框和標籤。 |
6 | wx.CheckBox
複選框顯示一個小的帶標籤的矩形框。單擊時,矩形內會出現一個複選標記,以指示已做出選擇。 |
7 | ComboBox & Choice 類
wx.ComboBox 物件提供一個專案列表供選擇。可以將其配置為下拉列表或永久顯示。wxPython API 包含 wx.Choice 類,其物件也是一個永久只讀的下拉列表。 |
8 | Wx.Gauge
Wx.Gauge 類物件顯示一個垂直或水平條,以圖形方式顯示遞增的數量。 |
9 | wx.Slider
wxPython API 包含 wx.Slider 類。它提供與捲軸相同的功能。滑塊提供了一種方便的方法來處理透過滑塊特定的 wx.EVT_SLIDER 事件繫結器拖動滑塊。 |
10 | wx.MenuBar
頂級視窗標題欄下方的水平條用於顯示一系列選單。它是 wxPython API 中 wx.MenuBar 類的物件。 |
11 | wx.Toolbar
如果 wx.Toolbar 物件的 style 引數設定為 wx.TB_DOCKABLE,則它將變為可停靠的。也可以使用 wxPython 的 AUIToolBar 類構造浮動工具欄。 |
12 | Wx.Dialog
雖然 Dialog 類物件看起來像 Frame,但它通常用作父框架頂部的彈出視窗。Dialog 的目的是從使用者那裡收集一些資料並將其傳送到父框架。 |
13 | wx.Notebook
wx.Notebook 視窗部件提供一個選項卡式控制元件。框架中的一個 Notebook 物件具有一個或多個選項卡(稱為頁面),每個頁面都有一個顯示控制元件佈局的面板。 |
14 | wx.SplitterWindow
此類的物件是一個佈局管理器,它包含兩個子視窗,其大小可以透過拖動它們之間的邊界來動態更改。Splitter 控制元件提供一個可以拖動以調整控制元件大小的控制代碼。 |
15 | HTMLWindow
wxHTML 庫包含用於解析和顯示 HTML 內容的類。雖然這並非旨在成為一個功能齊全的瀏覽器,但 wx.HtmlWindow 物件是一個通用的 HTML 檢視器。 |
16 | ListBox & ListCtrl
wx.ListBox 視窗部件顯示一個垂直可滾動的字串列表。預設情況下,列表中可以選擇單個專案。ListCtrl 視窗部件是一個高度增強的列表顯示和選擇工具。可以在報表檢視、列表檢視或圖示檢視中顯示多列列表。 |
wxPython - 事件處理
與以順序方式執行的控制檯模式應用程式不同,基於 GUI 的應用程式是事件驅動的。函式或方法是響應使用者操作(例如單擊按鈕、從集合中選擇專案或滑鼠單擊等,稱為事件)而執行的。
應用程式執行期間發生的事件相關資料儲存為從wx.Event派生的子類的物件。顯示控制元件(例如按鈕)是特定型別事件的源,併產生與其關聯的Event類物件。例如,單擊按鈕會發出wx.CommandEvent。此事件資料將分派到程式中的事件處理程式方法。wxPython 具有許多預定義的事件繫結器。事件繫結器封裝了特定視窗小部件(控制元件)、其關聯的事件型別和事件處理程式方法之間的關係。
例如,要在按鈕單擊事件上呼叫程式的OnClick() 方法,需要以下語句:
self.b1.Bind(EVT_BUTTON, OnClick)
Bind() 方法由所有顯示物件從wx.EvtHandler 類繼承。這裡的EVT_.BUTTON 是繫結器,它將按鈕單擊事件與OnClick() 方法關聯。
示例
在以下示例中,由拖動頂級視窗(在本例中為wx.Frame 物件)引起的MoveEvent 與使用wx.EVT_MOVE 繫結器的OnMove() 方法連線。程式碼顯示一個視窗。如果使用滑鼠移動它,則其瞬時座標將顯示在控制檯上。
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.
wxPython - 佈局管理
可以透過指定以畫素為單位測量的絕對座標,將GUI 視窗小部件放置在容器視窗內。座標相對於其建構函式的size 引數定義的視窗尺寸。視窗小部件在視窗內的位置由其建構函式的pos 引數定義。
import wx app = wx.App() window = wx.Frame(None, title = "wxPython Frame", size = (300,200)) panel = wx.Panel(window) label = wx.StaticText(panel, label = "Hello World", pos = (100,50)) window.Show(True) app.MainLoop()
但是,這種絕對定位由於以下原因並不合適:
即使調整視窗大小,視窗小部件的位置也不會改變。
在具有不同解析度的不同顯示裝置上的外觀可能不一致。
佈局修改很困難,因為它可能需要重新設計整個表單。
wxPython API 提供佈局類,用於更優雅地管理容器內視窗小部件的位置。佈局管理器相對於絕對定位的優點是:
- 視窗內的視窗小部件會自動調整大小。
- 確保在具有不同解析度的顯示裝置上外觀一致。
- 可以動態新增或刪除視窗小部件,而無需重新設計。
在wxPython 中,佈局管理器稱為Sizer。Wx.Sizer 是所有sizer 子類的基類。讓我們討論一些重要的sizer,例如wx.BoxSizer、wx.StaticBoxSizer、wx.GridSizer、wx.FlexGridSizer 和wx.GridBagSizer。
序號 | Sizer 和描述 |
---|---|
1 | BoxSizer
此sizer 允許以行方式或列方式排列控制元件。BoxSizer 的佈局由其orientation 引數(wxVERTICAL 或wxHORIZONTAL)確定。 |
2 | GridSizer
顧名思義,GridSizer 物件呈現一個二維網格。控制元件按從左到右、從上到下的順序新增到網格槽中。 |
3 | FlexiGridSizer
此sizer 也具有二維網格。但是,它在單元格中佈置控制元件方面提供了更多靈活性。 |
4 | GridBagSizer
GridBagSizer 是一個多功能的sizer。它提供了比FlexiGridSizer 更多的增強功能。子視窗小部件可以新增到網格內的特定單元格。 |
5 | StaticBoxSizer
StaticBoxSizer 將box sizer 放入靜態框中。它在框周圍提供一個邊框,以及頂部的標籤。 |
wxPython - 按鈕
按鈕視窗小部件在任何GUI 介面中使用最廣泛。它捕獲使用者生成的單擊事件。它最明顯的用途是觸發與其繫結的處理程式函式。
wxPython 類庫提供了不同型別的按鈕。有一個簡單傳統的按鈕,wx.Button 類物件,它帶有文字作為其標題。還提供了一個雙狀態按鈕,名為wx.ToggleButton。其按下或彈起狀態可以透過事件處理程式函式識別。
另一種型別的按鈕,wx.BitmapButton 顯示點陣圖(影像)作為其表面的圖示。
wx.Button 類和wx.ToggleButton 類的建構函式採用以下引數:
Wx.Button(parent, id, label, pos, size, style)
這些是wx.Button 類的一些重要方法:
序號 | 方法和描述 |
---|---|
1 | SetLabel() 以程式設計方式設定按鈕的標題 |
2 | GetLabel() 返回按鈕的標題 |
3 | SetDefault() 將按鈕設定為頂級視窗的預設按鈕。模擬按下Enter 鍵時的單擊事件 |
wx.ToggleButton 類的兩個重要方法是:
序號 | 方法和描述 |
---|---|
1 | GetValue() 返回切換按鈕的狀態(開/關) |
2 | SetValue() 以程式設計方式設定按鈕的狀態 |
為了建立點陣圖按鈕,首先需要根據影像檔案構造點陣圖物件。
最常用的wx.Bitmap 類建構函式的變體如下:
Wx.Bitmap(fiiename, wx.BITMAP_TYPE)
一些預定義的點陣圖型別常量是:
wx.BITMAP_TYPE_BMP |
wx.BITMAP_TYPE_ICO |
wx.BITMAP_TYPE_CUR |
wx.BITMAP_TYPE_TIFF |
wx.BITMAP_TYPE_TIF |
wx.BITMAP_TYPE_GIF |
wx.BITMAP_TYPE_PNG |
wx.BITMAP_TYPE_JPEG |
wx.BITMAP_TYPE_PCX |
wx.BITMAP_TYPE_ICON |
wx.BITMAP_TYPE_ANY |
此點陣圖物件用作wx.BitmapButton 類建構函式的引數之一。
Wx.BitmapButton(parent, id, bitmap, pos, size, style)
在某些作業系統平臺上,點陣圖按鈕可以同時顯示點陣圖和標籤。SetLabel() 方法分配標題。在其他平臺上,它用作內部標籤。
普通按鈕和點陣圖按鈕都會發出wx.CommandEvent。EVT_BUTTON 繫結器將處理程式函式與其關聯。
另一方面,切換按鈕使用wx.TOGGLEBUTTON 繫結器進行事件處理。
在以下示例中,所有三種類型的按鈕都放置在面板的垂直box sizer 中。
使用以下語句建立簡單的按鈕物件:
self.btn = wx.Button(panel, -1, "click Me")
切換按鈕由以下語句構造:
self.tbtn = wx.ToggleButton(panel , -1, "click to on")
這些按鈕使用以下語句新增到垂直sizer 中:
vbox.Add(self.btn,0,wx.ALIGN_CENTER) vbox.Add(self.tbtn,0,wx.EXPAND|wx.ALIGN_CENTER)
注意:由於wx.EXPAND 標誌,切換按鈕佔據了框架的整個寬度。
使用EVT_BUTTON 和EVT_TOGGLEBUTTON 繫結器,它們與各自的處理程式關聯。
self.btn.Bind(wx.EVT_BUTTON,self.OnClicked) self.tbtn.Bind(wx.EVT_TOGGLEBUTTON,self.OnToggle)
三個點陣圖按鈕新增到水平box sizer 中。這些按鈕顯示影像作為其標題的圖示。
bmp = wx.Bitmap("NEW.BMP", wx.BITMAP_TYPE_BMP) self.bmpbtn = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp, size = (bmp.GetWidth()+10, bmp.GetHeight()+10)) bmp1 = wx.Bitmap("OPEN.BMP", wx.BITMAP_TYPE_BMP) self.bmpbtn1 = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp1, size = (bmp.GetWidth()+10, bmp.GetHeight()+10)) bmp2 = wx.Bitmap("SAVE.BMP", wx.BITMAP_TYPE_BMP) self.bmpbtn2 = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp2, size = (bmp.GetWidth()+10, bmp.GetHeight()+10))
這三個按鈕的單擊事件定向到OnClicked() 方法。
self.bmpbtn.Bind(wx.EVT_BUTTON, self.OnClicked) self.bmpbtn1.Bind(wx.EVT_BUTTON, self.OnClicked) self.bmpbtn2.Bind(wx.EVT_BUTTON, self.OnClicked)
這些按鈕的內部標籤分別設定為NEW、OPEN 和SAVE。
OnClicked() 事件處理程式函式檢索導致單擊事件的源按鈕的標籤。該標籤將列印在控制檯上。
def OnClicked(self, event): btn = event.GetEventObject().GetLabel() print "Label of pressed button = ",btn
單擊切換按鈕時,將觸發OnToggle() 事件處理程式。其狀態由GetValue() 方法讀取,並據此設定按鈕的標題。
def OnToggle(self,event): state = event.GetEventObject().GetValue() if state == True: print "off" event.GetEventObject().SetLabel("click to off") else: print "on" event.GetEventObject().SetLabel("click to on")
完整的程式碼清單如下:
import wx class Mywin(wx.Frame): def __init__(self, parent, title): super(Mywin, self).__init__(parent, title = title,size = (200,150)) panel = wx.Panel(self) vbox = wx.BoxSizer(wx.VERTICAL) self.btn = wx.Button(panel,-1,"click Me") vbox.Add(self.btn,0,wx.ALIGN_CENTER) self.btn.Bind(wx.EVT_BUTTON,self.OnClicked) self.tbtn = wx.ToggleButton(panel , -1, "click to on") vbox.Add(self.tbtn,0,wx.EXPAND|wx.ALIGN_CENTER) self.tbtn.Bind(wx.EVT_TOGGLEBUTTON,self.OnToggle) hbox = wx.BoxSizer(wx.HORIZONTAL) bmp = wx.Bitmap("NEW.BMP", wx.BITMAP_TYPE_BMP) self.bmpbtn = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp, size = (bmp.GetWidth()+10, bmp.GetHeight()+10)) hbox.Add(self.bmpbtn,0,wx.ALIGN_CENTER) self.bmpbtn.Bind(wx.EVT_BUTTON,self.OnClicked) self.bmpbtn.SetLabel("NEW") bmp1 = wx.Bitmap("OPEN.BMP", wx.BITMAP_TYPE_BMP) self.bmpbtn1 = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp1, size = (bmp.GetWidth()+10, bmp.GetHeight()+10)) hbox.Add(self.bmpbtn1,0,wx.ALIGN_CENTER) self.bmpbtn1.Bind(wx.EVT_BUTTON,self.OnClicked) self.bmpbtn1.SetLabel("OPEN") bmp2 = wx.Bitmap("SAVE.BMP", wx.BITMAP_TYPE_BMP) self.bmpbtn2 = wx.BitmapButton(panel, id = wx.ID_ANY, bitmap = bmp2, size = (bmp.GetWidth()+10, bmp.GetHeight()+10)) hbox.Add(self.bmpbtn2,0,wx.ALIGN_CENTER) self.bmpbtn2.Bind(wx.EVT_BUTTON,self.OnClicked) self.bmpbtn2.SetLabel("SAVE") vbox.Add(hbox,1,wx.ALIGN_CENTER) panel.SetSizer(vbox) self.Centre() self.Show() self.Fit() def OnClicked(self, event): btn = event.GetEventObject().GetLabel() print "Label of pressed button = ",btn def OnToggle(self,event): state = event.GetEventObject().GetValue() if state == True: print "Toggle button state off" event.GetEventObject().SetLabel("click to off") else: print " Toggle button state on" event.GetEventObject().SetLabel("click to on") app = wx.App() Mywin(None, 'Button demo') app.MainLoop()
上述程式碼產生以下輸出:

按下按鈕的標籤 = click Me
切換按鈕狀態關閉
切換按鈕狀態開啟
按下按鈕的標籤 = NEW
按下按鈕的標籤 = OPEN
按下按鈕的標籤 = SAVE
wxPython - 可停靠視窗
wxAui 是wxWidgets API 中整合的先進使用者介面庫。Wx.aui.AuiManager 是AUI 框架中的核心類。
AuiManager 使用每個面板在wx.aui.AuiPanelInfo 物件中的資訊來管理與特定框架關聯的面板。讓我們瞭解PanelInfo 物件控制對接和浮動行為的各種屬性。
將可停靠視窗放在頂級框架中涉及以下步驟:
首先,建立一個AuiManager 物件。
self.mgr = wx.aui.AuiManager(self)
然後,設計一個具有所需控制元件的面板。
pnl = wx.Panel(self) pbox = wx.BoxSizer(wx.HORIZONTAL) text1 = wx.TextCtrl(pnl, -1, "Dockable", style = wx.NO_BORDER | wx.TE_MULTILINE) pbox.Add(text1, 1, flag = wx.EXPAND) pnl.SetSizer(pbox)
設定AuiPanelInfo 的以下引數。
方向:頂部、底部、左側、右側或中心
位置:多個面板可以放置在一個可停靠區域內。每個都給出一個位置編號。
行:多個面板顯示在一行中。就像多條工具欄出現在同一行中一樣。
層:面板可以分層放置。
使用此PanelInfo,將設計的面板新增到管理器物件中。
info1 = wx.aui.AuiPaneInfo().Bottom() self.mgr.AddPane(pnl,info1)
其餘的頂級視窗可以像往常一樣擁有其他控制元件。
完整的程式碼如下:
import wx import wx.aui class Mywin(wx.Frame): def __init__(self, parent, title): super(Mywin, self).__init__(parent, title = title, size = (300,300)) self.mgr = wx.aui.AuiManager(self) pnl = wx.Panel(self) pbox = wx.BoxSizer(wx.HORIZONTAL) text1 = wx.TextCtrl(pnl, -1, "Dockable", style = wx.NO_BORDER | wx.TE_MULTILINE) pbox.Add(text1, 1, flag = wx.EXPAND) pnl.SetSizer(pbox) info1 = wx.aui.AuiPaneInfo().Bottom() self.mgr.AddPane(pnl, info1) panel = wx.Panel(self) text2 = wx.TextCtrl(panel, size = (300,200), style = wx.NO_BORDER | wx.TE_MULTILINE) box = wx.BoxSizer(wx.HORIZONTAL) box.Add(text2, 1, flag = wx.EXPAND) panel.SetSizerAndFit(box) self.mgr.Update() self.Bind(wx.EVT_CLOSE, self.OnClose) self.Centre() self.Show(True) def OnClose(self, event): self.mgr.UnInit() self.Destroy() app = wx.App() Mywin(None,"Dock Demo") app.MainLoop()
上述程式碼產生以下輸出:

wxPython - 多文件介面
典型的GUI 應用程式可能有多個視窗。選項卡式和堆疊式視窗小部件允許一次啟用一個這樣的視窗。但是,很多時候這種方法可能不起作用,因為其他視窗的檢視被隱藏了。
同時顯示多個視窗的一種方法是將它們建立為獨立視窗。這稱為SDI(單文件介面)。這需要更多記憶體資源,因為每個視窗可能都有自己的菜單系統、工具欄等。
wxPython 中的MDI 框架提供了一個wx.MDIParentFrame 類。其物件充當多個子視窗的容器,每個子視窗都是wx.MDIChildFrame 類的物件。
子視窗位於父框架的MDIClientWindow 區域中。新增子框架後,父框架的選單欄會顯示一個“視窗”選單,其中包含以級聯或平鋪方式排列子視窗的按鈕。
示例
以下示例說明了使用MDIParentFrame 作為頂級視窗。名為NewWindow 的選單按鈕在客戶端區域中新增一個子視窗。可以新增多個視窗,然後以級聯或平鋪順序排列。
完整的程式碼如下:
import wx class MDIFrame(wx.MDIParentFrame): def __init__(self): wx.MDIParentFrame.__init__(self, None, -1, "MDI Parent", size = (600,400)) menu = wx.Menu() menu.Append(5000, "&New Window") menu.Append(5001, "&Exit") menubar = wx.MenuBar() menubar.Append(menu, "&File") self.SetMenuBar(menubar) self.Bind(wx.EVT_MENU, self.OnNewWindow, id = 5000) self.Bind(wx.EVT_MENU, self.OnExit, id = 5001) def OnExit(self, evt): self.Close(True) def OnNewWindow(self, evt): win = wx.MDIChildFrame(self, -1, "Child Window") win.Show(True) app = wx.App() frame = MDIFrame() frame.Show() app.MainLoop()
上述程式碼產生以下輸出:

wxPython - 繪圖API
GDI+(圖形繪製介面)、CoreGraphics 和Cairo 庫構成了wxPython 中繪圖API 的框架。wx.GraphicsContext 是主要的繪圖物件,使用它可以建立各種裝置上下文物件。
wx.DC 是一個抽象類。它的派生類用於在不同裝置上呈現圖形和文字。裝置上下文類是:
wx.ScreenDC:使用它在螢幕上繪圖,而不是單個視窗。
wx.ClientDC:使用它在視窗的客戶端區域(沒有邊框和其他裝飾的部分)上繪圖,但在wxPaintEvent 中不要使用它。
wx.PaintDC:使用它在視窗的客戶端區域上繪圖,但僅在wxPaintEvent 中使用。
wx.WindowDC:使用它在視窗的整個區域(包括裝飾)上繪圖。這在非Windows 平臺上可能不可用。
wxPython 的繪圖 API 提供了繪製形狀、文字和影像的不同函式。繪圖所需的 Colour、Pen、Brush 和 Font 等物件也可以使用 GDI 類構造。
wx.Colour 類
Colour 物件表示 RGB(紅、綠、藍)強度值的組合,每個值的範圍都是 0-255。有一些預定義的顏色物件,例如:
- wxBLACK
- wxBLUE
- wxCYAN
- wxGREEN
- wxYELLOW
- wxLIGHT_GREY
- wxRED
- wxWHITE
可以使用自定義的 RGB 值組合來建立wx.Colour 物件。
wx.Colour(r,g,b)
wx.Pen 類
Pen 物件確定圖形(如線、矩形、圓形等)的形狀的顏色、寬度和樣式。
預定義的 Pen 物件有:
wxBLACK_DASHED_PEN |
wxBLACK_PEN |
wxBLUE_PEN |
wxCYAN_PEN |
wxGREEN_PEN |
wxYELLOW_PEN |
wxGREY_PEN |
wxLIGHT_GREY_PEN |
wxMEDIUM_GREY_PEN |
wxRED_PEN |
wxTRANSPARENT_PEN |
wxWHITE_PEN |
預定義的 Pen 樣式有:
wx.SOLID |
wx.DOT |
wx.LONG_DASH |
wx.SHORT_DASH |
wx.DOT_DASH |
wx.TRANSPARENT |
wx.Brush 類
Brush 是另一個基本的圖形物件,用於填充矩形、橢圓形、圓形等形狀的背景。
自定義 Brush 物件需要 wx.Colour 和 Brush 樣式引數。以下是預定義的筆刷樣式列表:
wx.SOLID |
wx.STIPPLE |
wx.BDIAGONAL_HATCH |
wx.CROSSDIAG_HATCH |
wx.FDIAGONAL_HATCH |
wx.CROSS_HATCH |
wx.HORIZONTAL_HATCH |
wx.VERTICAL_HATCH |
wx.TRANSPARENT |
wxPython 有許多函式可以方便地繪製不同的形狀、文字和影像。
序號 | 函式和描述 |
---|---|
1 | DrawRectangle() 繪製給定尺寸的矩形 |
2 | DrawCircle() 在給定中心點和半徑處繪製一個圓形 |
3 | DrawEllipse() 繪製給定 x 和 y 半徑的橢圓形 |
4 | DrawLine() 繪製兩個 wx.Point 物件之間的直線 |
5 | DrawBitmap() 在給定位置繪製圖像 |
6 | DrawText() 在指定位置顯示給定的文字 |
示例
以下示例中實現了上述函式,並使用了 Pen、Brush、Colour 和 Font 物件。
完整的程式碼如下:
import wx class Mywin(wx.Frame): def __init__(self, parent, title): super(Mywin, self).__init__(parent, title = title,size = (500,300)) self.InitUI() def InitUI(self): self.Bind(wx.EVT_PAINT, self.OnPaint) self.Centre() self.Show(True) def OnPaint(self, e): dc = wx.PaintDC(self) brush = wx.Brush("white") dc.SetBackground(brush) dc.Clear() dc.DrawBitmap(wx.Bitmap("python.jpg"),10,10,True) color = wx.Colour(255,0,0) b = wx.Brush(color) dc.SetBrush(b) dc.DrawCircle(300,125,50) dc.SetBrush(wx.Brush(wx.Colour(255,255,255))) dc.DrawCircle(300,125,30) font = wx.Font(18, wx.ROMAN, wx.ITALIC, wx.NORMAL) dc.SetFont(font) dc.DrawText("Hello wxPython",200,10) pen = wx.Pen(wx.Colour(0,0,255)) dc.SetPen(pen) dc.DrawLine(200,50,350,50) dc.SetBrush(wx.Brush(wx.Colour(0,255,0), wx.CROSS_HATCH)) dc.DrawRectangle(380, 15, 90, 60) ex = wx.App() Mywin(None,'Drawing demo') ex.MainLoop()
上述程式碼產生以下輸出:

wxPython - 拖放
拖放功能對於使用者來說非常直觀。在許多桌面應用程式中都可以找到它,使用者只需用滑鼠拖動物件並將其放在另一個視窗上,即可將物件從一個視窗複製或移動到另一個視窗。
拖放操作包括以下步驟:
- 宣告一個放置目標
- 建立資料物件
- 建立 wx.DropSource
- 執行拖動操作
- 取消或接受放置
在 wxPython 中,有兩個預定義的放置目標:
- wx.TextDropTarget
- wx.FileDropTarget
許多 wxPython 小部件支援拖放活動。源控制元件必須啟用拖動,而目標控制元件必須能夠接受(或拒絕)拖動。
使用者正在拖動的源資料被放置在目標物件上。目標物件的 OnDropText() 消耗資料。如果需要,可以刪除源物件中的資料。
示例
在以下示例中,兩個 ListCtrl 物件水平放置在一個 Box Sizer 中。左側列表填充了 languages[] 資料。它被指定為拖動的源。右側列表是目標。
languages = ['C', 'C++', 'Java', 'Python', 'Perl', 'JavaScript', 'PHP', 'VB.NET','C#'] self.lst1 = wx.ListCtrl(panel, -1, style = wx.LC_LIST) self.lst2 = wx.ListCtrl(panel, -1, style = wx.LC_LIST) for lang in languages: self.lst1.InsertStringItem(0,lang)
第二個列表控制元件為空,是 TextDropTarget 類物件的引數。
class MyTextDropTarget(wx.TextDropTarget): def __init__(self, object): wx.TextDropTarget.__init__(self) self.object = object def OnDropText(self, x, y, data): self.object.InsertStringItem(0, data)
OnDropText() 方法將源資料新增到目標列表控制元件中。
拖動操作由事件繫結器初始化。
wx.EVT_LIST_BEGIN_DRAG(self, self.lst1.GetId(), self.OnDragInit)
OnDragInit() 函式將拖動資料放在目標上並從源中刪除。
def OnDragInit(self, event): text = self.lst1.GetItemText(event.GetIndex()) tobj = wx.PyTextDataObject(text) src = wx.DropSource(self.lst1) src.SetData(tobj) src.DoDragDrop(True) self.lst1.DeleteItem(event.GetIndex())
完整的程式碼如下:
import wx class MyTarget(wx.TextDropTarget): def __init__(self, object): wx.TextDropTarget.__init__(self) self.object = object def OnDropText(self, x, y, data): self.object.InsertStringItem(0, data) class Mywin(wx.Frame): def __init__(self, parent, title): super(Mywin, self).__init__(parent, title = title,size = (-1,300)) panel = wx.Panel(self) box = wx.BoxSizer(wx.HORIZONTAL) languages = ['C', 'C++', 'Java', 'Python', 'Perl', 'JavaScript', 'PHP', 'VB.NET','C#'] self.lst1 = wx.ListCtrl(panel, -1, style = wx.LC_LIST) self.lst2 = wx.ListCtrl(panel, -1, style = wx.LC_LIST) for lang in languages: self.lst1.InsertStringItem(0,lang) dt = MyTarget(self.lst2) self.lst2.SetDropTarget(dt) wx.EVT_LIST_BEGIN_DRAG(self, self.lst1.GetId(), self.OnDragInit) box.Add(self.lst1,0,wx.EXPAND) box.Add(self.lst2, 1, wx.EXPAND) panel.SetSizer(box) panel.Fit() self.Centre() self.Show(True) def OnDragInit(self, event): text = self.lst1.GetItemText(event.GetIndex()) tobj = wx.PyTextDataObject(text) src = wx.DropSource(self.lst1) src.SetData(tobj) src.DoDragDrop(True) self.lst1.DeleteItem(event.GetIndex()) ex = wx.App() Mywin(None,'Drag&Drop Demo') ex.MainLoop()
上述程式碼產生以下輸出:
