| Python的GUI編程 |
Python 提供了多個圖形開發界面的庫,以下是幾個常用的 Python GUI 庫:
tkinter: tkinter 模塊(Tk 接口)是 Python 的標准 Tk GUI 工具包的接口 .Tk 和 tkinter 可以在大多數的 Unix 平台下使用,同樣可以應用在 Windows 和 Macintosh 系統里。Tk8.0 的后續版本可以實現本地窗口風格,並良好地運行在絕大多數平台中。
wxPython:wxPython 是一款開源軟件,是 Python 語言的一套優秀的 GUI 圖形庫,允許 Python 程序員很方便的創建完整的、功能健全的 GUI 用戶界面。
Jython:Jython 程序可以和 Java 無縫集成。除了一些標准模塊,Jython 使用 Java 的模塊。Jython 幾乎擁有標准的Python 中不依賴於 C 語言的全部模塊。比如,Jython 的用戶界面將使用 Swing,AWT或者 SWT。Jython 可以被動態或靜態地編譯成 Java 字節碼。
| 使用tkinter庫實現簡易計算器 |
我們再仔細了解一下tkinter:
tkinter是一個開放源碼的圖形接口開發工具,原來是用TCL(Tool Command Language,工具命令語言)編寫的GUI函數庫,最初發展是從1991年開始,具有跨平台的特性,可以在Linux、Windows、Mac OS等操作系統上執行。tkinter工具提供許多圖形接口,例如標簽(Label)、菜單(Menu)、按鈕(Button)等。目前,tkinter工具已經移植到python語言,屬於python語言內置的模塊,在Python2版本中該模塊名稱是tkinter,在Python3版本中該模塊被稱為tkinter模塊。
| 導入 |
在安裝Python時,就已同時安裝此模塊了,只需導入即可:
from tkinter import *
在正式使用前可以先了解一下自己的tkinter版本:
import tkinter
print(tkinter.TkVersion)
執行結果:

一般8.5之后的功能比較齊全。
| 建立窗口 |
通常將使用Tk()方法建立的窗口稱為根除窗口,即root,可以取做其他名稱,本次實現簡易計算器,故取做calculator。之后我們可以在根窗口中建立許多控件或上層窗口。
root = Tk()
root.title("calcutor")
如果只是想建立窗口,要用mainloop()讓程序執行,放在程序最后一行。
root.mainloop()

上圖是以默認大小出現的名為calculator的根窗口
在GUI程序設計中,有時也將建立的窗口稱為容器(container)
| 容器 |
在此簡單介紹一下容器:
框架Frame是tkinter的容器控件,以下為Frame( )方法常用的options參數:
| 參數名 | 作用 |
|---|---|
| bg或background | 背景色彩 |
| borderwidth或bd | 標簽邊界寬度,默認是2 |
| cursor | 當鼠標光標在框架上時的光標形狀 |
| height | 框架的高度,單位是像素pixel |
| highlightbackground | 當框架沒有取得焦點時的顏色 |
| highlightcolor | 當框架取得焦點時的顏色 |
| relief | 默認是relief=FLAT,可由此控制框架外框 |
| width | 框架的寬度,單位是像素pixel,省略時會自行調整為實際寬度 |
import tkinter
from tkinter.constants import LEFT
root = tkinter.Tk()
root.title("calculator")
frame = tkinter.Frame(root,bg= "orange")
frame.pack()
Btn1=
tkinter.Button(frame,text="1",fg="orange")
Btn1.pack(side=LEFT,padx=5,pady=5)
root.mainloop()

如圖為利用Frame建立按鈕
說到按鈕,就不得不提到tkinter中的按鈕控件,這也是在實現簡易計算器中必不可少的部分,按鈕屬於tkinter中的組件,讓我們來了解一下組件有哪些
| tkinter組件 |
目前有15種tkinter組件,也叫部件,如下:
| 組件 | 描述 |
|---|---|
| Button | 按鈕控件;在程序中顯示按鈕 |
| Canvas | 畫布控件;顯示圖形元素如線條或文本 |
| Checkbutton | 多選框控件;用於在程序中提供多項選擇框 |
| Entry | 輸入控件;用於顯示簡單的文本內容 |
| Frame | 框架控件;在屏幕上顯示一個矩形區域,多用來作為容器 |
| Label | 標簽控件;可以顯示文本和位圖 |
| Listbox | 列表框控件;在Listbox窗口小部件是用來顯示一個字符串列表給用戶 |
| Menubutton | 菜單按鈕控件,用於顯示菜單項 |
| Menu | 菜單控件;顯示菜單欄,下拉菜單和彈出菜單 |
| Message | 消息控件;用來顯示多行文本,與label比較類似 |
| Radiobutton | 單選按鈕控件;顯示一個單選的按鈕狀態 |
| Scale | 范圍控件;顯示一個數值刻度,為輸出限定范圍的數字區間 |
| Scrollbar | 滾動條控件,當內容超過可視化區域時使用,如列表框 |
| Text | 文本控件;用於顯示多行文本 |
| Toplevel | 容器控件;用來提供一個單獨的對話框,和Frame比較類似 |
| Spinbox | 輸入控件;與Entry類似,但是可以指定輸入范圍值 |
| PanedWindow | PanedWindow是一個窗口布局管理的插件,可以包含一個或者多個子控件 |
| LabelFrame | labelframe 是一個簡單的容器控件。常用與復雜的窗口布局 |
| tkMessageBox | 用於顯示應用程序的消息框 |
| tkinter幾何管理 |
Tkinter控件有特定的幾何狀態管理方法,管理整個控件區域組織:
| 幾何方法 | 描述 |
|---|---|
| pack( ) | 包裝 |
| grid( ) | 網格 |
| place( ) | 位置 |
在本次實現簡易計算器中,我們預設需要有顯示區,按鍵0-9以及運算符號,這是簡易布局;還有鼠標點擊按鍵時,按鍵的值能顯示出來,能計算出運算結果,以及能夠清空來進行下一次輸入,這是完整設計。當然,如果想要更加完善得使用計算器,我們還希望它的界面能放大縮小。在這其中,我們會使用到Button控件,Label控件以及grid( )語法等。
在Flame( )的示例中展示了Button的用法,但是在實現簡易計算器的過程中,不同的按鈕需要傳遞的參數不同,此時我們需要使用Lambda表達式通過調用相同的方法但是傳遞不同參數的方式簡化設計。
| Lambda表達式 |
語法格式為:
lambda 參數值列表:表達式
參數值列表為輸入,表達式計算的結構為輸出
我們再給函數傳遞參數時,需要使用lambda函數

| grid方法 |
grid方法是一種以格狀或類似Excel電子表格方式包裝和定位窗口組件的方法,其語法格式為grid(options,···)
options參數可以是row、column、padx/pady、rowspan、columnspan、sticky等
row和column參數:

import tkinter
root = tkinter.Tk()
root.title("calculator")
lab = tkinter.Label(root,text="",bg="yellow",width=20)
btn7 = tkinter.Button(root,text="7",width=3)
lab .grid(row=0,column=0,columnspan=4)
btn7.grid(row=1,column=0,padx=5)
root.mainloop()
如圖為設置一個按鈕

以下為源代碼:
from tkinter import *
def calculate():
result = eval(equ.get())
equ.set(equ.get() + "=\n" + str(result))
def show(buttonString):
content = equ.get()
if content == "0":
content = ""
equ.set(content + buttonString)
def backspace():
equ.seet(str(equ.get()[:-1]))
def clear():
equ.set("0")
root = Tk()
root.title("calcutor")
equ = StringVar()
equ.set("0")
label = Label(root,width=25,height=2,relief="raised",anchor=SE,textvariable=equ)
label.grid(row=0,column=0,columnspan=4,padx=5,pady=5)
clearButton = Button(root,text="C",fg="blue",width=5,command=clear)
clearButton.grid(row = 1,column = 0)
Button(root,text="DEL",width=5,command=backspace).grid(row=1,column=1)
Button(root,text="%",width=5,command=lambda:show("%")).grid(row=1,column=2)
Button(root,text="/",width=5,command=lambda:show("/")).grid(row=1,column=3)
Button(root,text="7",width=5,command=lambda:show("7")).grid(row=2,column=0)
Button(root,text="8",width=5,command=lambda:show("8")).grid(row=2,column=1)
Button(root,text="9",width=5,command=lambda:show("9")).grid(row=2,column=2)
Button(root,text="x",width=5,command=lambda:show("*")).grid(row=2,column=3)
Button(root,text="4",width=5,command=lambda:show("4")).grid(row=3,column=0)
Button(root,text="5",width=5,command=lambda:show("5")).grid(row=3,column=1)
Button(root,text="6",width=5,command=lambda:show("6")).grid(row=3,column=2)
Button(root,text="-",width=5,command=lambda:show("-")).grid(row=3,column=3)
Button(root,text="1",width=5,command=lambda:show("1")).grid(row=4,column=0)
Button(root,text="2",width=5,command=lambda:show("2")).grid(row=4,column=1)
Button(root,text="3",width=5,command=lambda:show("3")).grid(row=4,column=2)
Button(root,text="+",width=5,command=lambda:show("+")).grid(row=4,column=3)
Button(root,text="0",width=12,
command=lambda:show("0")).grid(row=5,column=0,columnspan=2)
Button(root,text=".",width=5,
command=lambda:show(".")).grid(row=5,column=2)
Button(root,text="=",width=5,bg="yellow",
command=lambda:calculate()).grid(row=5,column=3)
root.mainloop()
