python之圖形界面

12.1 豐富的平臺

在編寫python GUI程序前,需要決定使用哪個GUI平臺。wxpython----跨平臺pythonGUI工具包

確保所選擇的二進制版本要對應python的版本,例如,針對python2.3進行編譯的wxpython並不能用於python2.4.


12.3.1 開始

開始需要wx模塊:

import wx


編寫wxPython程序的方法很多,但不可避免的事情是創建應用程序對象。基本的應用程序類叫做ex.App,它負責幕後所有的初始化。最簡單的wxPython程序應該像下面這樣:

import wx

app = wx.App

app.MainLoop()


如果wx.App無法工作,可能需要將它替換爲wx.PySimpleApp


12.3.2 窗口和組件

窗口也稱爲框架,它只是wx.Frame類的實例。wx框架中的部件都是由它們的父部件作爲構造函數的第一個參數的第一個參數創建的。如果正在創建一個單獨的窗口,就不需要考慮父部件,使用None即可,如代碼清單12-1所示。而且在調用app.MainLoop前需要調用窗口的Show方法-----否則它會一直隱藏。


創建並且顯示一個框架

import wx

app = wx.App()

win = wx.Frame(None)

win.Show()

app.MainLoop()


在框架上增加按鈕也很簡單----只要使用win作爲父參數實例化wx.Button即可

在框架上增加按鈕

import wx

app = wx.App()

win = wx.Frame(None)

btn = wx.Button(win)

win.show()

app.MainLoop()


12.3.3 標籤、標題和位置

可以在創建部件的時候使用構造函數的label參數設定它們的標籤。同樣,也可以用title參數設定框架的標題。

使用關鍵字參數增加標籤和標題

import wx

app = wx.App()

win = wx.Frame(None,title="Simple Editor")

loadButton = wx.Button(win,label='Open')

saveButton = wx.Button(win.label='Save')

win.Show()

app.MainLoop()


注意一下按鈕的佈局就能將隱藏的按鈕顯示。一個很基礎的方法是使用pos和size參數在構造函數內設置位置和尺寸。


設置按鈕位置

import wx

app = wx.App()

win = wx.Frame(None,title="Simple Editor",size=(410,335))

win.Show()

loadButton = wx.Button(win,label='Open',pos=(315,5),size=(80,25))

saveButton = wx.Button(win,label='Save',pos=(315,5),size=(80,25))

filename = wx.TextCtrl(win,pos=(5,5),size=(210,25))

contents = wx.TextCtrl(win,pos=(5,35),size=(390,260),style=wx.TE_MULTILINE | wx.HSCROLL)

app.MainLoop()


位置和尺寸都包括一對數值:位置包括x和y座標,而尺寸包括寬和高。

創建了兩個文本控件,每個都使用了自定義風格。默認的文本控件式文本框,就是一行可編輯的文本,沒有滾動條,爲了創建文本區只要使用style參數調整風格即可。style參數的值實際上是個整數。但不用直接指定,可以使用按位或運算符OR聯合wx模塊中具有特殊名字的風格來指定。本例中,我聯合了wx.TE_MULTINE來獲取多行文本區以及wx.HSCROLL來獲取水平滾動條。


12.3.4 更智能的佈局

讓組件隨窗口中的組件也會調整大小和位置。

使用尺寸器

import wx

app = wx.App()

win = wx.Frame(None,title="Simple Editor",size=(410,335))

bkg = wx.Panel(win)

loadButton = wx.Button(bkg,label='Open')

saveButton = wx.Button(bkg,label='Save')

filename = wx.TextCtrl(bkg)

contents = wx.TextCtrl(bkg,style=wx.TE_MULTILINE | wx.HSCROLL)

hbox = wx.BoxSizer()

hbox.Add(filename,proportion=1,flag=wx.EXPAND)

vbox.Add(loadButton,proportion=0,flag=wx.LEFT,border=5)

hbox.Add(saveButton,proportion=0,flag=wx.LEFT,border=5)

vbox = wx.BoxSizer(wx.VERTICAL)

vbox.Add(hbox,proportion=0,flag=wx.EXPAND | wx.ALL,border=5)

vbox.Add(contenxs,proportion=1,flag=wx.EXPAND | wx.LEFT | wx.BOTTOM | wx.RIGHT,border=5)

bkg.SetSizer(vbox)

win.Show()

app.MainLoop()


這段代碼的運行結果和前例相同,但是使用了相對座標而不是絕對座標。

wx.BoxSizer的構造函數帶有一個決定它是水平還是垂直的參數(wx.HORIZONTAL或者wx.VERTICAL),默認爲水平。Add方法有幾個參數,proportion參數根據在窗口改變大小時所分配的空間設置比例。例如,水平的BoxSizer中,filename組件的改變大小時獲取了全部的額外空間。如果這3個部件都把proportion設爲1,那麼都會獲得相等的空間。可以將proportion設定爲任何數。

flag參數類似構造函數中的style參數,可以使用按位或運算符連接構造符號常量對其進行構造。wx.EXPAND標記確保組件會擴展到所分配的空間中。而wx.LEFT,wx.RIGHT,wx.TOP,wx.BOTTOM和wx.ALL標記決定邊框參數應用於哪個邊,邊框參數用於設置邊緣寬度。



12.3.5 事件處理

在GUI術語中,用戶執行的動作叫做事件。你需要讓程序注意這些事件並且作爲反應。可以將函數綁定到所涉及的事件可能發生的組件上達到這個效果。當事件發生時,函數會被調用。利用部件的Bind方法可以將事件處理函數鏈接到給定的事件上。

假設寫了一個負責打開文件的函數,並將其命名爲load。然後就可以像下面這樣將該函數作爲loadButton的事件處理函數:

loadButton.Bind(wx.EVT_BUTTON,load)

我把函數鏈接到了按鈕---點擊按鈕的時候,函數被調用。名爲wx.EVT_BUTTON的符號常量表示一個按鈕事件。wx框架對於各種事件都有這樣的事件常量----從鼠標動作到鍵盤按鍵。


12.3.6 完成了的程序

現在需要兩個事件處理函數:load和save。當事件處理函數被調用時,它會收到一個事件對象作爲它唯一的參數,其中包括髮生了什麼事情的信息,但是在這裏可以忽略這方面的事情,因爲程序只關心點擊時發生的事情。

def load(event):

file = open(filename.GetValue())

contents.SetValue(file.read())

file.close()

def save(event):

file = open(filename.GetValue(),'w')

file.write(contents.GetValue())

file.close()


最終的GUI程序

import wx

def load(event):

file = open(filename.GetValue())

contents.SetValue(file.read())

file.close()

def save(event):

file = open(filename.GetValue(),'w')

file.write(contents.GetValue())

file.close()

app = wx.App()

win = wx.Frame(None,title="Simple Editor",size=(410,335))

bkg = wx.Panel(win)

loadButton = wx.Button(bkg,label='Open')

loadButton.Bind(wx.EVT_BUTTON,load)


saveButton = wx.Button(bkg,label='Save')

saveButton.Bind(wx.EVT_BUTTON,save)


filename = wx.TextCtrl(bkg)

contents = wx.TextCtrl(bkg,style=wx.TE_MULTILINE | wx.HSCROLL)

hbox = wx.BoxSizer()

hbox.Add(filename,proportion=1,flag=wx.EXPAND)

vbox.Add(loadButton,proportion=0,flag=wx.LEFT,border=5)

hbox.Add(saveButton,proportion=0,flag=wx.LEFT,border=5)


vbox = wx.BoxSizer(wx.VERTICAL)

vbox.Add(hbox,proportion=0,flag=wx.EXPAND | wx.ALL,border=5)

vbox.Add(contenxs,proportion=1,flag=wx.EXPAND | wx.LEFT | wx.BOTTOM | wx.RIGHT,border=5)

bkg.SetSizer(vbox)

win.Show()

app.MainLoop()


可以按照下面的步驟使用這個編輯器。

1.運行程序。應該看到一個和剛纔差不多的窗口

2.在文本區裏面打些字

3.在文本框內鍵入文件名。確保文件不存在,否則它會被覆蓋。

4.點擊save按鈕

5.關閉編輯器窗口

6.重啓程序

7.在文本框內鍵入同樣的文件名

8.點擊open按鈕。文件的文本內容應該會在大文本區內重現。

9.隨便編輯一下文件,再次保存。



12.4 但是我寧願用。。。

python的GUI工具包實在太多,所以我沒法將所有工具包都展示給你看。不過我可以給出一些流行的GUI包中的例子。

import wx

def hello(event):

print "Hello,world!"

app = wx.App()


win = wx.Frame(None,title="Hello,wxPython!",size=(200,100))

button = wx.Button(win,label="Hello")

button = Bind(wx.EVT_BUTTON,hello)

win.Show()

app.MainLoop()


12.4.1 使用Tkinter


Tkinter是個老牌的Python GUI程序。它由Tk GUI工具包包裝而來。

from Tkinter import *

def hello(): print 'Hello,world'

win = Tk()

win.title('Hello,Tkinter!')

win.geometry('200*100')

btn = Button(win,text='Hello ',command=hello)

btn.pack(expand=YES,fill=BOTH)

mainloop()


12.4.2 使用jython和Swing

如果正在使用jython,類似wxPython和Tkinter這樣的包就不能用了。唯一可用的GUI工具包是java標準庫包AWT和Swing。

下面是使用jython和Swing實現的GUI示例

from javax.Swing import *

import sys

def hello(event): print 'Hello,world!'

btn = JButton('Hello')

btn.actionPerformed = hello

win = JFrame('Hello,Swing!')

win.contenPane.add(btn)

def closeHandler(event): sys.exit()

win.windowClosing = closeHandler

btn.size = win.size = 200,100

win.show()


這裏增加了一個額外的事件處理函數,因爲關閉按鈕在java Swing中沒有任何有用的默認行爲。另外,無須顯式地進入主事件循環,因爲它是和程序並運行的。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章