當前流行的計算機桌面應用程序大多數為圖形化用戶(hù)界面(Graphic User Interface,GUI),即通過(guò)鼠標對菜單、按鈕等圖形化元素觸發(fā)指令,并從標簽、對話(huà)框等圖型化顯示容器中獲取人機對話(huà)信息。
Python自帶了tkinter 模塊,實(shí)質(zhì)上是一種流行的面向對象的GUI工具包 TK 的Python編程接口,提供了快速便利地創(chuàng )建GUI應用程序的方法。其圖像化編程的基本步驟通常包括:
2.1、根窗體是圖像化應用程序的根控制器,是tkinter的底層控件的實(shí)例。當導入tkinter模塊后,調用 Tk()方法可初始化一個(gè)根窗體實(shí)例 root ,用 title() 方法可設置其標題文字,用geometry()方法可以設置窗體的大?。ㄒ韵袼貫閱挝唬?。將其置于主循環(huán)中,除非用戶(hù)關(guān)閉,否則程序始終處于運行狀態(tài)。執行該程序,一個(gè)窗體就呈現出來(lái)了。在這個(gè)主循環(huán)的根窗體中,可持續呈現中的其他可視化控件實(shí)例,監測事件的發(fā)生并執行相應的處理程序。下面是根窗體呈現示例:
from tkinter import *
root= Tk()
root.title('我的第一個(gè)Python窗體')
root.geometry('240x240') # 這里的乘號不是 * ,而是小寫(xiě)英文字母 x
root.mainloop()
根窗體呈現示例
2.2、tkinter 常用控件
| 控件 | 名稱(chēng) | 作用 |
|---|---|---|
| Button | 按鈕 | 單擊觸發(fā)事件 |
| Canvas | 畫(huà)布 | 繪制圖形或繪制特殊控件 |
| Checkbutton | 復選框 | 多項選擇 |
| Entry | 輸入框 | 接收單行文本輸入 |
| Frame | 框架 | 用于控件分組 |
| Label | 標簽 | 單行文本顯示 |
| Lisbox | 列表框 | 顯示文本列表 |
| Menu | 菜單 | 創(chuàng )建菜單命令 |
| Message | 消息 | 多行文本標簽,與Label 用法類(lèi)似 |
| Radiobutton | 單選按鈕 | 從互斥的多個(gè)選項中做單項選擇 |
| Scale | 滑塊 | 默認垂直方向,鼠標拖動(dòng)改變數值形成可視化交互 |
| Scrollbar | 滑動(dòng)條 | 默認垂直方向,課鼠標拖動(dòng)改變數值,可與 Text、Lisbox、Canvas等控件配合移動(dòng)可視化空間 |
| Text | 文本框 | 接收或輸出顯示多行文本 |
| Toplevel | 新建窗體容器 | 在頂層創(chuàng )建新窗體 |
控件的共同屬性:在窗體上呈現的可視化控件,通常包括尺寸、顏色、字體、相對位置、浮雕樣式、圖標樣式和懸停光標形狀等共同屬性。不同的控件由于形狀和功能不同,又有其特征屬性。在初始化根窗體和根窗體主循環(huán)之間,可實(shí)例化窗體控件,并設置其屬性。父容器可為根窗體或其他容器控件實(shí)例。常見(jiàn)的控件共同屬性如下表:
| 屬性 | 說(shuō)明 | 取值 |
|---|---|---|
| anchor | 文本起始位置 | CENTER(默認),E,S,W,N,NE,SE,SW,NW |
| bg | 背景色 | 無(wú) |
| bd | 加粗(默認 2 像素) | 無(wú) |
| bitmap | 黑白二值圖標 | 網(wǎng)上查找 |
| cursor | 鼠標懸停光標 | 網(wǎng)上查找 |
| font | 字體 | 無(wú) |
| fg | 前景色 | 無(wú) |
| height | 高(文本控件的單位為行,不是像素) | 無(wú) |
| image | 顯示圖像 | 無(wú) |
| justify | 多行文本的對其方式 | CENTER(默認),LEFT,RIGHT,TOP,BOTTOM |
| padx | 水平擴展像素 | 無(wú) |
| pady | 垂直擴展像素 | 無(wú) |
| relief | 3D浮雕樣式 | FLAT,RAISED,SUNKEN,GROOVE,RIDGE |
| state | 控件實(shí)例狀態(tài)是否可用 | NORMAL(默認),DISABLED |
| width | 寬(文本控件的單位為行,不是像素) | 無(wú) |
標簽及常見(jiàn)屬性示例:
from tkinter import *
root = Tk()
lb = Label(root,text='我是第一個(gè)標簽',\
bg='#d3fbfb',\
fg='red',\
font=('華文新魏',32),\
width=20,\
height=2,\
relief=SUNKEN)
lb.pack()
root.mainloop()
Label(root,text='我是第一個(gè)標簽',font='華文新魏').pack() 屬性 relief 為控件呈現出來(lái)的3D浮雕樣式,有 FLAT(平的)、RAISED(凸起的)、SUNKEN(凹陷的)、GROOVE(溝槽狀邊緣)和 RIDGE(脊狀邊緣) 5種。
控件呈現的5種浮雕樣式
2.2、控件布局
控件的布局通常有pack()、grid() 和 place() 三種方法。
2.2.1、pack()方法:是一種簡(jiǎn)單的布局方法,如果不加參數的默認方式,將按布局語(yǔ)句的先后,以最小占用空間的方式自上而下地排列控件實(shí)例,并且保持控件本身的最小尺寸。如下的例子:
用pack() 方法不加參數排列標簽。為看清楚各控件所占用的空間大小,文本用了不同長(cháng)度的中英文,并設置relief=GROOVE的凹陷邊緣屬性。如下所示:
from tkinter import *
root = Tk()
lbred = Label(root,text="Red",fg="Red",relief=GROOVE)
lbred.pack()
lbgreen = Label(root,text="綠色",fg="green",relief=GROOVE)
lbgreen.pack()
lbblue = Label(root,text="藍",fg="blue",relief=GROOVE)
lbblue.pack()
root.mainloop()
使用pack()方法可設置 fill、side 等屬性參數。其中,參數fill 可取值:fill=X,fill=Y或fill=BOTH,分別表示允許控件向水平方向、垂直方向或二維伸展填充未被占用控件。參數 side 可取值:side=TOP(默認),side=LEFT,side=RIGHT,side=BOTTOM,分別表示本控件實(shí)例的布局相對于下一個(gè)控件實(shí)例的方位。如下例子:
用pack()方法加參數排列標簽
from tkinter import *
root = Tk()
lbred = Label(root,text="Red",fg="Red",relief=GROOVE)
lbred.pack()
lbgreen = Label(root,text="綠色",fg="green",relief=GROOVE)
lbgreen.pack(side=RIGHT)
lbblue = Label(root,text="藍",fg="blue",relief=GROOVE)
lbblue.pack(fill=X)
root.mainloop()
2.2.2、grid()方法:是基于網(wǎng)格的布局。先虛擬一個(gè)二維表格,再在該表格中布局控件實(shí)例。由于在虛擬表格的單元中所布局的控件實(shí)例大小不一,單元格也沒(méi)有固定或均一的大小,因此其僅用于布局的定位。pack()方法與grid()方法不能混合使用。
grid()方法常用布局參數如下:
看下面的例子:用grid()方法排列標簽,設想有一個(gè)3x4的表格,起始行、列序號均為0.將標簽lbred 至于第2列第0行;將標簽lbgreen置于第0列第1行;將標簽lbblue置于第1列起跨2列第2行,占20像素寬。

pack()方法排列標簽
from tkinter import *
root = Tk()
lbred = Label(root,text="Red",fg="Red",relief=GROOVE)
lbred.grid(column=2,row=0)
lbgreen = Label(root,text="綠色",fg="green",relief=GROOVE)
lbgreen.grid(column=0,row=1)
lbblue = Label(root,text="藍",fg="blue",relief=GROOVE)
lbblue.grid(column=1,columnspan=2,ipadx=20,row=2)
root.mainloop()
2.2.3、place()方法:根據控件實(shí)例在父容器中的絕對或相對位置參數進(jìn)行布局。其常用布局參數如下:
x,y:控件實(shí)例在根窗體中水平和垂直方向上的其實(shí)位置(單位為像素)。注意,根窗體左上角為0,0,水平向右,垂直向下為正方向。
relx,rely:控件實(shí)例在根窗體中水平和垂直方向上起始布局的相對位置。即相對于根窗體寬和高的比例位置,取值在0.0~1.0之間。
height,width:控件實(shí)例本身的高度和寬度(單位為像素)。
relheight,relwidth:控件實(shí)例相對于根窗體的高度和寬度比例,取值在0.0~1.0之間。
利用place()方法配合relx,rely和relheight,relwidth參數所得的到的界面可自適應根窗體尺寸的大小。place()方法與grid()方法可以混合使用。如下例子:利用place()方法排列消息(多行標簽)。

place()方法排列消息
from tkinter import *
root = Tk()
root.geometry('320x240')
msg1 = Message(root,text='''我的水平起始位置相對窗體 0.2,垂直起始位置為絕對位置 80 像素,我的高度是窗體高度的0.4,寬度是200像素''',relief=GROOVE)
msg1.place(relx=0.2,y=80,relheight=0.4,width=200)
root.mainloop()
3、tkinter常見(jiàn)控件的特征屬性
3.1、文本輸入和輸出相關(guān)控件:文本的輸入與輸出控件通常包括:標簽(Label)、消息(Message)、輸入框(Entry)、文本框(Text)。他們除了前述共同屬性外,都具有一些特征屬性和功能。
標簽(Label)和 消息(Message):除了單行與多行的不同外,屬性和用法基本一致,用于呈現文本信息。值得注意的是:屬性text通常用于實(shí)例在第一次呈現時(shí)的固定文本,而如果需要在程序執行后發(fā)生變化,則可以使用下列方法之一實(shí)現:1、用控件實(shí)例的configure()方法來(lái)改變屬性text的值,可使顯示的文本發(fā)生變化;2、先定義一個(gè)tkinter的內部類(lèi)型變量var=StringVar() 的值也可以使顯示文本發(fā)生變化。
看下面的一個(gè)例子:制作一個(gè)電子時(shí)鐘,用root的after()方法每隔1秒time模塊以獲取系統當前時(shí)間,并在標簽中顯示出來(lái)。
方法一:利用configure()方法或config()來(lái)實(shí)現文本變化。

import tkinter
import time
def gettime():
timestr = time.strftime("%H:%M:%S") # 獲取當前的時(shí)間并轉化為字符串
lb.configure(text=timestr) # 重新設置標簽文本
root.after(1000,gettime) # 每隔1s調用函數 gettime 自身獲取時(shí)間
root = tkinter.Tk()
root.title('時(shí)鐘')
lb = tkinter.Label(root,text='',fg='blue',font=("黑體",80))
lb.pack()
gettime()
root.mainloop()
方法二:利用textvariable變量屬性來(lái)實(shí)現文本變化。
import tkinter
import time
def gettime():
var.set(time.strftime("%H:%M:%S")) # 獲取當前時(shí)間
root.after(1000,gettime) # 每隔1s調用函數 gettime 自身獲取時(shí)間
root = tkinter.Tk()
root.title('時(shí)鐘')
var=tkinter.StringVar()
lb = tkinter.Label(root,textvariable=var,fg='blue',font=("黑體",80))
lb.pack()
gettime()
root.mainloop()
文本框(Text):
文本框的常用方法如下:
| 方法 | 功能 |
|---|---|
| delete(起始位置,[,終止位置]) | 刪除指定區域文本 |
| get(起始位置,[,終止位置]) | 獲取指定區域文本 |
| insert(位置,[,字符串]...) | 將文本插入到指定位置 |
| see(位置) | 在指定位置是否可見(jiàn)文本,返回布爾值 |
| index(標記) | 返回標記所在的行和列 |
| mark_names() | 返回所有標記名稱(chēng) |
| mark_set(標記,位置) | 在指定位置設置標記 |
| mark_unset(標記) | 去除標記 |
上表位置的取值可為整數,浮點(diǎn)數或END(末尾),例如0.0表示第0列第0行
如下一個(gè)例子:每隔1秒獲取一次當前日期的時(shí)間,并寫(xiě)入文本框中,如下:本例中調用 datetime.now()獲取當前日期時(shí)間,用insert()方法每次從文本框txt的尾部(END)開(kāi)始追加文本。

獲取當前日期的時(shí)間并寫(xiě)入文本中
from tkinter import *
import time
import datetime
def gettime():
s=str(datetime.datetime.now())+'\n'
txt.insert(END,s)
root.after(1000,gettime) # 每隔1s調用函數 gettime 自身獲取時(shí)間
root=Tk()
root.geometry('320x240')
txt=Text(root)
txt.pack()
gettime()
root.mainloop()
輸入框(Entry):通常作為功能比較單一的接收單行文本輸入的控件,雖然也有許多對其中文本進(jìn)行操作的方法,但通常用的只有取值方法get()和用于刪除文本的delete(起始位置,終止位置),例如:清空輸入框為delete(0,END)。
3.2、按鈕(Button):主要是為響應鼠標單擊事件觸發(fā)運行程序所設的,故其除控件共有屬性外,屬性command是最為重要的屬性。通常,將按鈕要觸發(fā)執行的程序以函數形式預先定義,然后可以用一下兩種方法調用函數。Button按鈕的狀態(tài)有:'normal','active','disabled'
直接調用函數。參數表達式為“command=函數名”,注意函數名后面不要加括號,也不能傳遞參數。如下面的command=run1:
利用匿名函數調用函數和傳遞參數。參數的表達式為“command=lambda”:函數名(參數列表)。例如下面的:"command=lambda:run2(inp1.get(),inp2.get())"。
看下面的例子:1.從兩個(gè)輸入框去的輸入文本后轉為浮點(diǎn)數值進(jìn)行加法運算,要求每次單擊按鈕產(chǎn)生的算是結果以文本的形式追加到文本框中,將原輸入框清空。2.按鈕方法一不傳參數調用函數run1()實(shí)現,按鈕“方法二”用lambda調用函數run2(x,y)同時(shí)傳遞參數實(shí)現。

簡(jiǎn)單加法器
from tkinter import *
def run1():
a = float(inp1.get())
b = float(inp2.get())
s = '%0.2f+%0.2f=%0.2f\n' % (a, b, a + b)
txt.insert(END, s) # 追加顯示運算結果
inp1.delete(0, END) # 清空輸入
inp2.delete(0, END) # 清空輸入
def run2(x, y):
a = float(x)
b = float(y)
s = '%0.2f+%0.2f=%0.2f\n' % (a, b, a + b)
txt.insert(END, s) # 追加顯示運算結果
inp1.delete(0, END) # 清空輸入
inp2.delete(0, END) # 清空輸入
root = Tk()
root.geometry('460x240')
root.title('簡(jiǎn)單加法器')
lb1 = Label(root, text='請輸入兩個(gè)數,按下面兩個(gè)按鈕之一進(jìn)行加法計算')
lb1.place(relx=0.1, rely=0.1, relwidth=0.8, relheight=0.1)
inp1 = Entry(root)
inp1.place(relx=0.1, rely=0.2, relwidth=0.3, relheight=0.1)
inp2 = Entry(root)
inp2.place(relx=0.6, rely=0.2, relwidth=0.3, relheight=0.1)
# 方法-直接調用 run1()
btn1 = Button(root, text='方法一', command=run1)
btn1.place(relx=0.1, rely=0.4, relwidth=0.3, relheight=0.1)
# 方法二利用 lambda 傳參數調用run2()
btn2 = Button(root, text='方法二', command=lambda: run2(inp1.get(), inp2.get()))
btn2.place(relx=0.6, rely=0.4, relwidth=0.3, relheight=0.1)
# 在窗體垂直自上而下位置60%處起,布局相對窗體高度40%高的文本框
txt = Text(root)
txt.place(rely=0.6, relheight=0.4)
root.mainloop()
3.3、單選按鈕:(Radiobutton)是為了響應故鄉排斥的若干單選項的單擊事件以觸發(fā)運行自定義函數所設的,該控件排除具有共有屬性外,還具有顯示文本(text)、返回變量(variable)、返回值(value)、響應函數名(command)等重要屬性。響應函數名“command=函數名”的用法與Button相同,函數名最后也要加括號。返回變量variable=var通常應預先聲明變量的類(lèi)型var=IntVar()或var=StringVar(),在所調用的函數中方可用var.get()方法獲取被選中實(shí)例的value值。例如下面:

單選按鈕
from tkinter import *
def Mysel():
dic = {0:'甲',1:'乙',2:'丙'}
s = "您選了" + dic.get(var.get()) + "項"
lb.config(text = s)
root = Tk()
root.title('單選按鈕')
lb = Label(root)
lb.pack()
var = IntVar()
rd1 = Radiobutton(root,text="甲",variable=var,value=0,command=Mysel)
rd1.pack()
rd2 = Radiobutton(root,text="乙",variable=var,value=1,command=Mysel)
rd2.pack()
rd3 = Radiobutton(root,text="丙",variable=var,value=2,command=Mysel)
rd3.pack()
root.mainloop()
3.4、復選框:(Checkbutton) 是為了返回多個(gè)選項值的交互控件,通常不直接觸發(fā)函數的執行。該控件除具有共有屬性外,還具有顯示文本(text)、返回變量(variable)、選中返回值(onvalue)和未選中默認返回值(offvalue)等重要屬性。返回變量variable=var 通??梢灶A先逐項分別聲明變量的類(lèi)型var=IntVar() (默認)或 var=StringVar(), 在所調用的函數中方可分別調用 var.get()方法 取得被選中實(shí)例的 onvalue或offvalue值。復選框實(shí)例通常還可分別利用 select()、deselect()和 toggle() 方法對其進(jìn)行選中、清除選中和反選操作。
如下的例子: 利用復選框實(shí)現,單擊OK,可以將選中的結果顯示在標簽上。效果如下:

復選框的應用
方法:利用函數中的 if-else 分支實(shí)現多項顯示
from tkinter import *
import tkinter
def run():
if(CheckVar1.get()==0 and CheckVar2.get()==0 and CheckVar3.get()==0 and CheckVar4.get()==0):
s = '您還沒(méi)選擇任何愛(ài)好項目'
else:
s1 = "足球" if CheckVar1.get()==1 else ""
s2 = "籃球" if CheckVar2.get() == 1 else ""
s3 = "游泳" if CheckVar3.get() == 1 else ""
s4 = "田徑" if CheckVar4.get() == 1 else ""
s = "您選擇了%s %s %s %s" % (s1,s2,s3,s4)
lb2.config(text=s)
root = tkinter.Tk()
root.title('復選框')
lb1=Label(root,text='請選擇您的愛(ài)好項目')
lb1.pack()
CheckVar1 = IntVar()
CheckVar2 = IntVar()
CheckVar3 = IntVar()
CheckVar4 = IntVar()
ch1 = Checkbutton(root,text='足球',variable = CheckVar1,onvalue=1,offvalue=0)
ch2 = Checkbutton(root,text='籃球',variable = CheckVar2,onvalue=1,offvalue=0)
ch3 = Checkbutton(root,text='游泳',variable = CheckVar3,onvalue=1,offvalue=0)
ch4 = Checkbutton(root,text='田徑',variable = CheckVar4,onvalue=1,offvalue=0)
ch1.pack()
ch2.pack()
ch3.pack()
ch4.pack()
btn = Button(root,text="OK",command=run)
btn.pack()
lb2 = Label(root,text='')
lb2.pack()
root.mainloop()
3.5、列表框 與 組合框:
| 方法 | 功能描述 |
|---|---|
| curselection() | 返回光標選中項目編號的元組,注意并不是單個(gè)的整數 |
| delete(起始位置,終止位置) | 刪除項目,終止位置可省略,全部清空為delete(0,END) |
| get(起始位置,終止位) | 返回范圍所含項目文本的元組,終止位置可忽略 |
| insert(位置,項目元素) | 插入項目元素(若有多項,可用列表或元組類(lèi)型賦值),若位置為END,則將項目元素添加在最后 |
| size() | 返回列表框行數 |
執行自定義函數時(shí),通常使用“實(shí)例名.surselection()” 或 “selected” 來(lái)獲取選中項的位置索引。由于列表框實(shí)質(zhì)上就是將Python 的列表類(lèi)型數據可視化呈現,在程序實(shí)現時(shí),也可直接對相關(guān)列表數據進(jìn)行操作,然后再通過(guò)列表框展示出來(lái),而不必拘泥于可視化控件的方法??聪旅娴囊粋€(gè)例子:實(shí)現列表框的初始化、添加、插入、修改、刪除和清空操作,如下:

列表框的應用
from tkinter import *
def ini():
Lstbox1.delete(0,END)
list_items = ["數學(xué)","物理","化學(xué)","語(yǔ)文","外語(yǔ)"]
for item in list_items:
Lstbox1.insert(END,item)
def clear():
Lstbox1.delete(0,END)
def ins():
if entry.get() != '':
if Lstbox1.curselection() == ():
Lstbox1.insert(Lstbox1.size(),entry.get())
else:
Lstbox1.insert(Lstbox1.curselection(),entry.get())
def updt():
if entry.get() != '' and Lstbox1.curselection() != ():
selected=Lstbox1.curselection()[0]
Lstbox1.delete(selected)
Lstbox1.insert(selected,entry.get())
def delt():
if Lstbox1.curselection() != ():
Lstbox1.delete(Lstbox1.curselection())
root = Tk()
root.title('列表框實(shí)驗')
root.geometry('320x240')
frame1 = Frame(root,relief=RAISED)
frame1.place(relx=0.0)
frame2 = Frame(root,relief=GROOVE)
frame2.place(relx=0.5)
Lstbox1 = Listbox(frame1)
Lstbox1.pack()
entry = Entry(frame2)
entry.pack()
btn1 = Button(frame2,text='初始化',command=ini)
btn1.pack(fill=X)
btn2 = Button(frame2,text='添加',command=ins)
btn2.pack(fill=X)
btn3 = Button(frame2,text='插入',command=ins) # 添加和插入功能實(shí)質(zhì)上是一樣的
btn3.pack(fill=X)
btn4 = Button(frame2,text='修改',command=updt)
btn4.pack(fill=X)
btn5 = Button(frame2,text='刪除',command=delt)
btn5.pack(fill=X)
btn6 = Button(frame2,text='清空',command=clear)
btn6.pack(fill=X)
root.mainloop()
3.5.2、組合框:(Combobox) 實(shí)質(zhì)上是帶文本框的上拉列表框,其功能也將是Python 的列表類(lèi)型數據可視化呈現,并提供用戶(hù)單選或多選所列條目以形成人機交互。在圖形化界面設計時(shí),由于其具有靈活的界面,因此往往比列表框更受喜愛(ài)。但該控件并不包含在 tkinter 模塊中,而是與 TreeView、Progressbar、Separator等控件一同包含在tkinter 的子模塊ttk中。如果使用該控件,應先與from tkinter import ttk 語(yǔ)句引用ttk子模塊,然后創(chuàng )建組合框實(shí)例: 實(shí)例名=Combobox(根對象,[屬性列表])
指定變量var=StringVar(),并設置實(shí)例屬性 textvariable = var,values=[列表...]。組合框控件常用方法有:獲得所選中的選項值get()和獲得所選中的選項索引current()。
看下面的一個(gè)例子:實(shí)現四則運算計算器,將兩個(gè)操作數分別填入兩個(gè)文本框后,通過(guò)選擇組合框中的算法觸發(fā)運算,如下:

組合框的應用
from tkinter.ttk import *
def calc(event):
a = float(t1.get())
b = float(t2.get())
dic = {0:a+b,1:a-b,2:a*b,3:a/b}
c = dic[comb.current()]
lbl.config(text=str(c))
root = Tk()
root.title('四則運算')
root.geometry('320x240')
t1 = Entry(root)
t1.place(relx=0.1,rely=0.1,relwidth=0.2,relheight=0.1)
t2 = Entry(root)
t2.place(relx=0.5,rely=0.1,relwidth=0.2,relheight=0.1)
var = StringVar()
comb = Combobox(root,textvariable=var,values=['加','減','乘','除',])
comb.place(relx=0.1,rely=0.5,relwidth=0.2)
comb.bind('<<ComboboxSelected>>',calc)
lbl=Label(root,text='結果')
lbl.place(relx=0.5,rely=0.7,relwidth=0.2,relheight=0.3)
root.mainloop()
3.6、滑塊:(Scale) 是一種 直觀(guān)地進(jìn)行數值輸入的交互控件,其主要屬性見(jiàn)下表:
| 屬性 | 功能描述 |
|---|---|
| from_ | 起始值(最小可取值) |
| lable | 標簽文字,默認為無(wú) |
| length | 滑塊控件實(shí)例寬(水平方向)或 高(垂直方向),默認為100像素 |
| orient | 滑塊控件實(shí)例呈現方向,VERTCAL或HORIZONTAL(默認) |
| repeatdelay | 鼠標響應延時(shí),默認為 300ms |
| resolution | 分辨精度,即最小值間隔 |
| sliderlength | 滑塊寬度,默認為30 像素 |
| state | 狀態(tài),若設置 state=DISABLED,則滑塊控件實(shí)例不可用 |
| tickinterval | 標尺間隔,默認為0,若設置過(guò)小,則會(huì )重疊 |
| to | 終止值(最大可取值) |
| variable | 返回數值類(lèi)型,可為IntVar(整數)、DoubleVar(浮點(diǎn)數)、或 StringVar(字符串) |
| width | 控件實(shí)例本身的寬度,默認為15像素 |
滑塊控件實(shí)例的主要方法比較簡(jiǎn)單,有 get()和set(值),分別為取值和將滑塊設在某特定值上?;瑝K實(shí)例也可綁定鼠標左鍵釋放事件<ButtoonRelease-1>,并在執行函數中添加參數event來(lái)實(shí)現事件響應。
例如:在一個(gè)窗體上設計一個(gè)200像素寬的水平滑塊,取值范圍為1.0~5.0,分辨精度為0.05,刻度間隔為 1,用鼠標拖動(dòng)滑塊后釋放鼠標可讀取滑塊值并顯示在標簽上。效果如下:

滑塊控件的應用
from tkinter import *
def show(event):
s = '滑塊的取值為' + str(var.get())
lb.config(text=s)
root = Tk()
root.title('滑塊實(shí)驗')
root.geometry('320x180')
var=DoubleVar()
scl = Scale(root,orient=HORIZONTAL,length=200,from_=1.0,to=5.0,label='請拖動(dòng)滑塊',tickinterval=1,resolution=0.05,variable=var)
scl.bind('<ButtonRelease-1>',show)
scl.pack()
lb = Label(root,text='')
lb.pack()
root.mainloop()
3.7、菜單:(Menu)用于可視化地為一系列的命令分組,從而方便用戶(hù)找到和觸發(fā)執行這些命令。這里Menu所實(shí)例化別的主要是菜單,其通式為:
菜單實(shí)例名=Menu(根窗體)
菜單分組1=Menu(菜單實(shí)例名)
菜單實(shí)例名.add_cascade(<label=菜單分組1 顯示文本>,<menu=菜單分組1>)
菜單分組1.add_command(<label=命令1文本>,<command=命令1函數名>)
其中較為常見(jiàn)的方法有:add_cascade()、add_command()和add_separator(),分別用于添加一個(gè)菜單分組、添加一條菜單命令和添加一條分割線(xiàn)。
利用Menu控件也可以創(chuàng )建快捷菜單(又稱(chēng)為上下文菜單)。通常需要右擊彈出的控件實(shí)例綁定鼠標右擊響應事件<Button-3>,并指向一個(gè)捕獲event參數的自定義函數,在該自定義函數中,將鼠標的觸發(fā)位置event.x_root 和 event.y_root以post()方法傳給菜單。
例子:仿照window自帶的“記事本”中的文件和編輯 菜單,實(shí)現在主菜單個(gè)快捷菜單上觸發(fā)菜單命令,并相應改變窗體上的標簽的文本內容。效果如下:

菜單和快捷菜單
from tkinter import *
def new():
s = '新建'
lb1.config(text=s)
def ope():
s = '打開(kāi)'
lb1.config(text=s)
def sav():
s = '保存'
lb1.config(text=s)
def cut():
s = '剪切'
lb1.config(text=s)
def cop():
s = '復制'
lb1.config(text=s)
def pas():
s = '粘貼'
lb1.config(text=s)
def popupmenu(event):
mainmenu.post(event.x_root,event.y_root)
root = Tk()
root.title('菜單實(shí)驗')
root.geometry('320x240')
lb1 = Label(root,text='顯示信息',font=('黑體',32,'bold'))
lb1.place(relx=0.2,rely=0.2)
mainmenu = Menu(root)
menuFile = Menu(mainmenu) # 菜單分組 menuFile
mainmenu.add_cascade(label="文件",menu=menuFile)
menuFile.add_command(label="新建",command=new)
menuFile.add_command(label="打開(kāi)",command=ope)
menuFile.add_command(label="保存",command=sav)
menuFile.add_separator() # 分割線(xiàn)
menuFile.add_command(label="退出",command=root.destroy)
menuEdit = Menu(mainmenu) # 菜單分組 menuEdit
mainmenu.add_cascade(label="編輯",menu=menuEdit)
menuEdit.add_command(label="剪切",command=cut)
menuEdit.add_command(label="復制",command=cop())
menuEdit.add_command(label="粘貼",command=pas())
root.config(menu=mainmenu)
root.bind('Button-3',popupmenu) # 根窗體綁定鼠標右擊響應事件
root.mainloop()
3.8、子窗體:用Toplevel可新建一個(gè)顯示在最前面的子窗體,其通式為: 字體實(shí)例名=Toplevel(根窗體),子窗體與根窗體類(lèi)似,也可設置title、geomerty等屬性,并在畫(huà)布上布局其他控件。如下的例子:在根窗體上創(chuàng )建菜單,觸發(fā)創(chuàng )建一個(gè)新的窗體

根窗體與子窗體
from tkinter import *
def newwind():
winNew = Toplevel(root)
winNew.geometry('320x240')
winNew.title('新窗體')
lb2 = Label(winNew,text='我在新窗體上')
lb2.place(relx=0.2,rely=0.2)
btClose=Button(winNew,text='關(guān)閉',command=winNew.destroy)
btClose.place(relx=0.7,rely=0.5)
root = Tk()
root.title('新建窗體實(shí)驗')
root.geometry('320x240')
lb1 = Label(root,text='主窗體',font=('黑體',32,'bold'))
lb1.place(relx=0.2,rely=0.2)
mainmenu = Menu(root)
menuFile = Menu(mainmenu)
mainmenu.add_cascade(label='菜單',menu=menuFile)
menuFile.add_command(label='新窗體',command=newwind)
menuFile.add_separator()
menuFile.add_command(label='退出',command=root.destroy)
root.config(menu=mainmenu)
root.mainloop()
關(guān)閉窗體程序運行的方法通常用 destory(),而不建議用 quit()。用Toplevel 所創(chuàng )建的子窗體是非模式(Modeless)的窗體,雖然初建時(shí)子窗體在最前面,但根窗體上的控件實(shí)例也是可以被操作的。
3.9、模式對話(huà)框(Modal):是相對于前面介紹的非模式窗體而言的,所彈出的對話(huà)框必須應答,在關(guān)閉之前無(wú)法操作其后面的其他窗體。常見(jiàn)的模式對話(huà)框有消息對話(huà)框、輸入對話(huà)框、文件選擇對話(huà)框、顏色選擇對話(huà)框等。
3.9.1、交互對話(huà)框
(一)、消息對話(huà)框: 引用 tkinter.messagebox 包,可使用消息對話(huà)框函數。執行這些函數,可彈出模式消息對話(huà)框,并根據用戶(hù)的響應但會(huì )一個(gè)布爾值。其通式為:
消息對話(huà)框函數(<title=標題文本>,<message=消息文本>,[其他參數]) 看下面的例子:?jiǎn)螕舭粹o,彈出確認取消對話(huà)框,并將用戶(hù)回答顯示在標簽中。效果如下:

確定取消對話(huà)框
from tkinter import *
import tkinter.messagebox
def xz():
answer=tkinter.messagebox.askokcancel('請選擇','請選擇確定或取消')
if answer:
lb.config(text='已確認')
else:
lb.config(text='已取消')
root = Tk()
lb = Label(root,text='')
lb.pack()
btn=Button(root,text='彈出對話(huà)框',command=xz)
btn.pack()
root.mainloop()
(二)、輸入對話(huà)框: 引用tkinter.simpledialog包,可彈出輸入對話(huà)框,用以接收用戶(hù)的簡(jiǎn)單輸入。輸入對話(huà)框常用 askstring()、askfloat()和askfloat() 三種函數,分別用于接收字符串、整數和浮點(diǎn)數類(lèi)型的輸入。
如下面的例子:單擊按鈕,彈出輸入對話(huà)框,接收文本輸入顯示在窗體的標簽上。如下:

輸入對話(huà)框
from tkinter.simpledialog import *
def xz():
s=askstring('請輸入','請輸入一串文字')
lb.config(text=s)
root = Tk()
lb = Label(root,text='')
lb.pack()
btn=Button(root,text='彈出輸入對話(huà)框',command=xz)
btn.pack()
root.mainloop()
3.9.2、文件選擇對話(huà)框:引用tkinter.filedialog包,可彈出文件選擇對話(huà)框,讓用戶(hù)直觀(guān)地選擇一個(gè)或一組文件,以供進(jìn)一步的文件操作。常用的文件選擇對話(huà)框函數有 askopenfilename()、askopenfilenames()和asksaveasfilename(),分別用于進(jìn)一步打開(kāi)一個(gè)文件、一組文件和保存文件。其中,askopenfilename()和asksaveasfilenamme()函數的返回值類(lèi)型為包含文件路徑的文件名字符串,而askopenfilenames()函數的返回值類(lèi)型為元組。
例如:?jiǎn)螕舭粹o,彈出文件選擇對話(huà)框(“打開(kāi)”對話(huà)框),并將用戶(hù)所選擇的文件路徑和文件名顯示在窗體的標簽上。如下

文件選擇對話(huà)框
from tkinter import *
import tkinter.filedialog
def xz():
filename=tkinter.filedialog.askopenfilename()
if filename != '':
lb.config(text='您選擇的文件是'+filename)
else:
lb.config(text='您沒(méi)有選擇任何文件')
root = Tk()
lb = Label(root,text='')
lb.pack()
btn=Button(root,text='彈出文件選擇對話(huà)框',command=xz)
btn.pack()
root.mainloop()
3.9.3、顏色選擇對話(huà)框:引用tkinter.colorchooser包,可使用 askcolor()函數彈出模式顏色選擇對話(huà)框,讓用戶(hù)可以個(gè)性化地設置顏色屬性。該函數的返回形式為包含RGB十進(jìn)制浮點(diǎn)元組和RGB十六進(jìn)制字符串的元組類(lèi)型,例如:“((135.527343.52734375,167.65234375,186.7265625)),'#87a7ba'”。通常,可將其轉換為字符串類(lèi)型后,再截取以十六進(jìn)制數表示的RGB顏色字符串用于為屬性賦值。
舉例:?jiǎn)螕舭粹o,彈出顏色選擇對話(huà)框,并將用戶(hù)所選擇的顏色設置為窗體上標簽的背景顏色,如下:

顏色選擇對話(huà)框
from tkinter import *
import tkinter.colorchooser
def xz():
color=tkinter.colorchooser.askcolor()
colorstr=str(color)
print('打印字符串%s 切掉后=%s' % (colorstr,colorstr[-9:-2]))
lb.config(text=colorstr[-9:-2],background=colorstr[-9:-2])
root = Tk()
lb = Label(root,text='請關(guān)注顏色的變化')
lb.pack()
btn=Button(root,text='彈出顏色選擇對話(huà)框',command=xz)
btn.pack()
root.mainloop()
用tkinter 可將用戶(hù)事件與自定義函數綁定,用鍵盤(pán)或鼠標的動(dòng)作事件來(lái)響應觸發(fā)自定義函數的執行。其通式為:
控件實(shí)例.bind(<事件代碼>,<函數名>)
其中,事件代碼通常以半角小于號“<”和大于號“>” 界定,包括事件和按鍵等 2~3個(gè)部分,它們之間用減號分隔,常見(jiàn)事件代碼見(jiàn)下表:
| 事件 | 事件代碼 | 備注 |
|---|---|---|
| 單擊鼠標左鍵 | <ButtonPress-1> | 可簡(jiǎn)寫(xiě)為<Button-1> 或 <1> |
| 單擊鼠標中鍵 | <ButtonPress-2> | 可簡(jiǎn)寫(xiě)為<Button-2> 或 <2> |
| 單擊鼠標右鍵 | <ButtonPress-3> | 可簡(jiǎn)寫(xiě)為<Button-3> 或 <3> |
| 釋放鼠標左鍵 | <ButtonRelease-1> | --- |
| 釋放鼠標中鍵 | <ButtonRelease-2> | --- |
| 釋放鼠標右鍵 | <ButtonRelease-3> | --- |
| 按住鼠標左鍵移動(dòng) | <B1-Motion> | --- |
| 按住鼠標中鍵移動(dòng) | <B2-Motion> | --- |
| 按住鼠標右鍵移動(dòng) | <B3-Motion> | --- |
| 轉動(dòng)鼠標滾輪 | <MouseWheel> | --- |
| 雙擊鼠標左鍵 | <Double-Button-1> | --- |
| 鼠標進(jìn)入控件實(shí)例 | <Enter> | 注意與回車(chē)事件的區別 |
| 鼠標離開(kāi)控件實(shí)例 | <Leave> | --- |
| 鍵盤(pán)任意鍵 | <Key> | --- |
| 字母和數字 | < Key-字母>,例如<key-a>、<Key-A> | 簡(jiǎn)寫(xiě)不帶小于和大于號,例如:a,A和1等 |
| 回車(chē) | <Return> | <Tab>,<Shift>,<Control>(注意不能用<Ctrl>),<Alt>等類(lèi)同 |
| 空格 | <Space> | --- |
| 方向鍵 | <Up> ,<Down>,<Left>,<Right> | --- |
| 功能鍵 | <Fn>例如:<F1>等 | --- |
| 組合鍵 | 鍵名之間以減號鏈接,例如<Control-k>,<Shift-6>,<Alt-Up>等 | 注意大小寫(xiě) |
例如,將框架控件實(shí)例frame 綁定鼠標右鍵單擊事件,調用自定義函數 myfunc()可表示為"frame.bind('<Button-3>',myfunc)",注意: myfunc后面沒(méi)有括號。將控件實(shí)例綁定到鍵盤(pán)事件和部分光標不落在具體控件實(shí)例上的鼠標事件時(shí),還需要設置該實(shí)例執行focus_set() 方法獲得焦點(diǎn),才能對事件持續響應。例如: frame.focus_set()。所調用的自定義函數若需要利用鼠標或鍵盤(pán)的響應值,可將event作為參數,通過(guò)event的屬性獲取。event的屬性見(jiàn)下表:
| event屬性 | 意義 |
|---|---|
| x或y(注意是小寫(xiě)) | 相對于事件綁定控件實(shí)例左上角的坐標值(像素) |
| root_x或root_y(注意是小寫(xiě)) | 相對于顯示屏幕左上角的坐標值(像素) |
| char | 可顯示的字符,若按鍵不可顯示,則返回為空字符串 |
| keysysm | 字符或字符型按鍵名,如:“a”或“Escape” |
| keysysm_num | 按鍵的十進(jìn)制 ASCII 碼值 |
例如:將標簽綁定鍵盤(pán)任意鍵觸發(fā)事件并獲取焦點(diǎn),并將按鍵字符顯示在標簽上

響應鍵盤(pán)事件
from tkinter import *
def show(event):
s=event.keysym
lb.config(text=s)
root=Tk()
root.title('按鍵實(shí)驗')
root.geometry('200x200')
lb=Label(root,text='請按鍵',font=('黑體',48))
lb.bind('<Key>',show)
lb.focus_set()
lb.pack()
root.mainloop()
聯(lián)系客服