一、前言
由於本篇文章較長,所以下面給出內容目錄方便跳轉閱讀,當然也可以用博客頁面最右側的文章目錄導航欄進行跳轉查閱。
一、前言
二、Tkinter 是什么
三、Tkinter 控件詳細介紹
1. Tkinter 模塊元素簡要說明
2. 常用窗口部件及簡要說明:
四、動手實踐學習
1. 創建主窗口及Label部件(標簽)創建使用
2. Button窗口部件
3. Entry窗口部件
4. Text窗口部件
5. Listbox窗口部件
6. Radiobutton窗口部件
7. Checkbutton窗口部件
8. Scale窗口部件
9. Canvas窗口部件
10. Menu窗口部件
11. Frame 窗口部件
12. messageBox窗口部件
13. 窗口部件三種放置方式pack/grid/place
14. 綜合練習,用戶登錄窗口例子
15. 其他部件后續再補充...
二、Tkinter是什么
Tkinter 是使用 python 進行窗口視窗設計的模塊。Tkinter模塊("Tk 接口")是Python的標准Tk GUI工具包的接口。作為 python 特定的GUI界面,是一個圖像的窗口,tkinter是python 自帶的,可以編輯的GUI界面,我們可以用GUI 實現很多直觀的功能,比如想開發一個計算器,如果只是一個程序輸入,輸出窗口的話,是沒用用戶體驗的。所有開發一個圖像化的小窗口,就是必要的。
對於稍有GUI編程經驗的人來說,Python的Tkinter界面庫是非常簡單的。python的GUI庫非常多,選擇Tkinter,一是最為簡單,二是自帶庫,不需下載安裝,隨時使用,三則是從需求出發,Python作為一種腳本語言,一種膠水語言,一般不會用它來開發復雜的桌面應用,它並不具備這方面的優勢,使用Python,可以把它作為一個靈活的工具,而不是作為主要開發語言,那么在工作中,需要制作一個小工具,肯定是需要有界面的,不僅自己用,也能分享別人使用,在這種需求下,Tkinter是足夠勝任的!
這篇文章主要做一個簡單概述和實踐編程,對於從沒有接觸過GUI的新手,在腦中樹立一個基本的界面編程概念,同時自己也能學會如何簡單的實現一些小的圖形窗口功能。
對於Tkinter編程,可以用兩個比喻來理解:
- 第一個,作畫。我們都見過美術生寫生的情景,先支一個畫架,放上畫板,蒙上畫布,構思內容,用鉛筆畫草圖,組織結構和比例,調色板調色,最后畫筆勾勒。相應的,對應到tkinter編程,那么我們的顯示屏就是支起來的畫架,根窗體就是畫板,在tkinter中則是Toplevel,畫布就是tkinter中的容器(Frame),畫板上可以放很多張畫布(Convas),tkinter中的容器中也可以放很多個容器,繪畫中的構圖布局則是tkinter中的布局管理器(幾何管理器),繪畫的內容就是tkinter中的一個個小組件,一幅畫由許多元素構成,而我們的GUI界面,就是有一個個組件拼裝起來的,它們就是widget。
- 第二個,我們小時候都玩過積木,只要發揮創意,相同的積木可以堆出各種造型。tkinter的組件也可以看做一個個積木,形狀或許不同,其本質都是一樣的,就是一個積木,不管它長什么樣子,它始終就是積木!所以這些小組件都有許多共性,另外,個人認為,學習界面編程,最重要的不是一開始學習每個積木的樣子,不是學習每個組件怎么用,而是這些組件該怎么放。初始學習中,怎么放遠遠比怎么用重要的多。網上有大量的文章資料,基本全是介紹組件怎么用的,對於怎么放,也就是tkinter中的布局管理器,都是一筆帶過,這對初學者有點本末倒置,或許絕大部分是轉載的原因吧,極少是自己真正寫的。組件怎么用不是最迫切的,用到的時候再去了解也不遲,邊用邊學反而更好。因此我將專門寫一章,詳細介紹布局管理器的使用。
三、Tkinter 控件詳細介紹
1. Tkinter 模塊元素簡要說明
![]() |
The Button Widget
|
2. 常用窗口部件及簡要說明:
Tkinter支持16個核心的窗口部件,這個16個核心窗口部件類簡要描述如下:
Button:一個簡單的按鈕,用來執行一個命令或別的操作。
Canvas:組織圖形。這個部件可以用來繪制圖表和圖,創建圖形編輯器,實現定制窗口部件。
Checkbutton:代表一個變量,它有兩個不同的值。點擊這個按鈕將會在這兩個值間切換。
Entry:文本輸入域。
Frame:一個容器窗口部件。幀可以有邊框和背景,當創建一個應用程序或dialog(對話)版面時,幀被用來組織其它的窗口部件。
Label:顯示一個文本或圖象。
Listbox:顯示供選方案的一個列表。listbox能夠被配置來得到radiobutton或checklist的行為。
Menu:菜單條。用來實現下拉和彈出式菜單。
Menubutton:菜單按鈕。用來實現下拉式菜單。
Message:顯示一文本。類似label窗口部件,但是能夠自動地調整文本到給定的寬度或比率。
Radiobutton:代表一個變量,它可以有多個值中的一個。點擊它將為這個變量設置值,並且清除與這同一變量相關的其它radiobutton。
Scale:允許你通過滑塊來設置一數字值。
Scrollbar:為配合使用canvas, entry, listbox, and text窗口部件的標准滾動條。
Text:格式化文本顯示。允許你用不同的樣式和屬性來顯示和編輯文本。同時支持內嵌圖象和窗口。
Toplevel:一個容器窗口部件,作為一個單獨的、最上面的窗口顯示。
messageBox:消息框,用於顯示你應用程序的消息框。(Python2中為tkMessagebox)
注意在Tkinter中窗口部件類沒有分級;所有的窗口部件類在樹中都是兄弟關系。
所有這些窗口部件提供了Misc和幾何管理方法、配置管理方法和部件自己定義的另外的方法。此外,Toplevel類也提供窗口管理接口。這意味一個典型的窗口部件類提供了大約150種方法。
四、動手實踐學習
1. 創建主窗口及Label部件(標簽)創建使用
我們要學習使用上面提到的這些控件首先要創建一個主窗口,就像作畫一樣,先要架好架子和畫板,然后才能在上面放畫紙和各種繪畫元素,創建好主窗口才能在上面放置各種控件元素。而創建過程是很簡單的,如下:
示例代碼:
-
#!/usr/bin/env python
-
# -*- coding: utf-8 -*-
-
# author:洪衛
-
-
import tkinter as tk # 使用Tkinter前需要先導入
-
-
# 第1步,實例化object,建立窗口window
-
window = tk.Tk()
-
-
# 第2步,給窗口的可視化起名字
-
window.title( 'My Window')
-
-
# 第3步,設定窗口的大小(長 * 寬)
-
window.geometry( '500x300') # 這里的乘是小x
-
-
# 第4步,在圖形界面上設定標簽
-
l = tk.Label(window, text= '你好!this is Tkinter', bg='green', font=('Arial', 12), width=30, height=2)
-
# 說明: bg為背景,font為字體,width為長,height為高,這里的長和高是字符的長和高,比如height=2,就是標簽有2個字符這么高
-
-
# 第5步,放置標簽
-
l.pack() # Label內容content區域放置位置,自動調節尺寸
-
# 放置lable的方法有:1)l.pack(); 2)l.place();
-
-
# 第6步,主窗口循環顯示
-
window.mainloop()
-
# 注意,loop因為是循環的意思,window.mainloop就會讓window不斷的刷新,如果沒有mainloop,就是一個靜態的window,傳入進去的值就不會有循環,mainloop就相當於一個很大的while循環,有個while,每點擊一次就會更新一次,所以我們必須要有循環
-
# 所有的窗口文件都必須有類似的mainloop函數,mainloop是窗口文件的關鍵的關鍵。
測試效果:
2. Button窗口部件
簡單說明:
Button(按鈕)部件是一個標准的Tkinter窗口部件,用來實現各種按鈕。按鈕能夠包含文本或圖象,並且你能夠將按鈕與一個Python函數或方法相關聯。當這個按鈕被按下時,Tkinter自動調用相關聯的函數或方法。
按鈕僅能顯示一種字體,但是這個文本可以跨行。另外,這個文本中的一個字母可以有下划線,例如標明一個快捷鍵。默認情況,Tab鍵用於將焦點移動到一個按鈕部件。
什么時候用按鈕部件
簡言之,按鈕部件用來讓用戶說“馬上給我執行這個任務”,通常我們用顯示在按鈕上的文本或圖象來提示。按鈕通常用在工具條中或應用程序窗口中,並且用來接收或忽略輸入在對話框中的數據。關於按鈕和輸入的數據的配合,可以參看Checkbutton和Radiobutton部件。
如何創建:
普通的按鈕很容易被創建,僅僅指定按鈕的內容(文本、位圖、圖象)和一個當按鈕被按下時的回調函數即可:
b = tk.Button(window, text="hit me", command=hit_me)
沒有回調函數的按鈕是沒有用的,當你按下這個按鈕時它什么也不做。你可能在開發一個應用程序的時候想實現這種按鈕,比如為了不干擾你的beta版的測試者:
b = tk.Button(window, text="Help", command=DISABLED)
示例代碼:
-
#!/usr/bin/env python
-
# -*- coding: utf-8 -*-
-
# author:洪衛
-
-
import tkinter as tk # 使用Tkinter前需要先導入
-
-
# 第1步,實例化object,建立窗口window
-
window = tk.Tk()
-
-
# 第2步,給窗口的可視化起名字
-
window.title( 'My Window')
-
-
# 第3步,設定窗口的大小(長 * 寬)
-
window.geometry( '500x300') # 這里的乘是小x
-
-
# 第4步,在圖形界面上設定標簽
-
var = tk.StringVar() # 將label標簽的內容設置為字符類型,用var來接收hit_me函數的傳出內容用以顯示在標簽上
-
l = tk.Label(window, textvariable=var, bg= 'green', fg='white', font=('Arial', 12), width=30, height=2)
-
# 說明: bg為背景,fg為字體顏色,font為字體,width為長,height為高,這里的長和高是字符的長和高,比如height=2,就是標簽有2個字符這么高
-
l.pack()
-
-
# 定義一個函數功能(內容自己自由編寫),供點擊Button按鍵時調用,調用命令參數command=函數名
-
on_hit = False
-
def hit_me():
-
global on_hit
-
if on_hit == False:
-
on_hit = True
-
var.set( 'you hit me')
-
else:
-
on_hit = False
-
var.set( '')
-
-
# 第5步,在窗口界面設置放置Button按鍵
-
b = tk.Button(window, text= 'hit me', font=('Arial', 12), width=10, height=1, command=hit_me)
-
b.pack()
-
-
# 第6步,主窗口循環顯示
-
window.mainloop()
測試效果:
3. Entry窗口部件
簡單說明:
Entry是tkinter類中提供的的一個單行文本輸入域,用來輸入顯示一行文本,收集鍵盤輸入(類似 HTML 中的 text)。
什么時候用:
需要用戶輸入用戶信息時,比如我們平時使用軟件、登錄網頁時,用戶交互界面讓我們登錄賬戶信息等時候可以用到。
示例代碼:
-
#!/usr/bin/env python
-
# -*- coding: utf-8 -*-
-
# author:洪衛
-
-
import tkinter as tk # 使用Tkinter前需要先導入
-
-
# 第1步,實例化object,建立窗口window
-
window = tk.Tk()
-
-
# 第2步,給窗口的可視化起名字
-
window.title( 'My Window')
-
-
# 第3步,設定窗口的大小(長 * 寬)
-
window.geometry( '500x300') # 這里的乘是小x
-
-
# 第4步,在圖形界面上設定輸入框控件entry並放置控件
-
e1 = tk.Entry(window, show= '*', font=('Arial', 14)) # 顯示成密文形式
-
e2 = tk.Entry(window, show= None, font=('Arial', 14)) # 顯示成明文形式
-
e1.pack()
-
e2.pack()
-
-
# 第5步,主窗口循環顯示
-
window.mainloop()
測試效果:
4. Text窗口部件
簡單說明:
Text是tkinter類中提供的的一個多行文本區域,顯示多行文本,可用來收集(或顯示)用戶輸入的文字(類似 HTML 中的 textarea),格式化文本顯示,允許你用不同的樣式和屬性來顯示和編輯文本,同時支持內嵌圖象和窗口。
什么時候用:
在需要顯示編輯用戶、產品多行信息時,比如顯示用戶詳細描述文字,產品簡介等等,支持隨時編輯。
示例代碼:
-
#!/usr/bin/env python
-
# -*- coding: utf-8 -*-
-
# author:洪衛
-
-
import tkinter as tk # 使用Tkinter前需要先導入
-
-
# 第1步,實例化object,建立窗口window
-
window = tk.Tk()
-
-
# 第2步,給窗口的可視化起名字
-
window.title( 'My Window')
-
-
# 第3步,設定窗口的大小(長 * 寬)
-
window.geometry( '500x300') # 這里的乘是小x
-
-
# 第4步,在圖形界面上設定輸入框控件entry框並放置
-
e = tk.Entry(window, show = None)#顯示成明文形式
-
e.pack()
-
-
# 第5步,定義兩個觸發事件時的函數insert_point和insert_end(注意:因為Python的執行順序是從上往下,所以函數一定要放在按鈕的上面)
-
def insert_point(): # 在鼠標焦點處插入輸入內容
-
var = e.get()
-
t.insert( 'insert', var)
-
def insert_end(): # 在文本框內容最后接着插入輸入內容
-
var = e.get()
-
t.insert( 'end', var)
-
-
# 第6步,創建並放置兩個按鈕分別觸發兩種情況
-
b1 = tk.Button(window, text= 'insert point', width=10,
-
height= 2, command=insert_point)
-
b1.pack()
-
b2 = tk.Button(window, text= 'insert end', width=10,
-
height= 2, command=insert_end)
-
b2.pack()
-
-
# 第7步,創建並放置一個多行文本框text用以顯示,指定height=3為文本框是三個字符高度
-
t = tk.Text(window, height= 3)
-
t.pack()
-
-
# 第8步,主窗口循環顯示
-
window.mainloop()
測試效果:
5. Listbox窗口部件
簡單說明:
Text是tkinter類中提供的的列表框部件,顯示供選方案的一個列表。listbox能夠被配置來得到radiobutton或checklist的行為。
什么時候用:
在有一個很多內容選項組成的列表提供用戶選擇時會用到。
示例代碼:
-
#!/usr/bin/env python
-
# -*- coding: utf-8 -*-
-
# author:洪衛
-
-
import tkinter as tk # 使用Tkinter前需要先導入
-
-
# 第1步,實例化object,建立窗口window
-
window = tk.Tk()
-
-
# 第2步,給窗口的可視化起名字
-
window.title( 'My Window')
-
-
# 第3步,設定窗口的大小(長 * 寬)
-
window.geometry( '500x300') # 這里的乘是小x
-
-
# 第4步,在圖形界面上創建一個標簽label用以顯示並放置
-
var1 = tk.StringVar() # 創建變量,用var1用來接收鼠標點擊具體選項的內容
-
l = tk.Label(window, bg= 'green', fg='yellow',font=('Arial', 12), width=10, textvariable=var1)
-
l.pack()
-
-
# 第6步,創建一個方法用於按鈕的點擊事件
-
def print_selection():
-
value = lb.get(lb.curselection()) # 獲取當前選中的文本
-
var1.set(value) # 為label設置值
-
-
# 第5步,創建一個按鈕並放置,點擊按鈕調用print_selection函數
-
b1 = tk.Button(window, text= 'print selection', width=15, height=2, command=print_selection)
-
b1.pack()
-
-
# 第7步,創建Listbox並為其添加內容
-
var2 = tk.StringVar()
-
var2.set(( 1,2,3,4)) # 為變量var2設置值
-
# 創建Listbox
-
lb = tk.Listbox(window, listvariable=var2) #將var2的值賦給Listbox
-
# 創建一個list並將值循環添加到Listbox控件中
-
list_items = [ 11,22,33,44]
-
for item in list_items:
-
lb.insert( 'end', item) # 從最后一個位置開始加入值
-
lb.insert( 1, 'first') # 在第一個位置加入'first'字符
-
lb.insert( 2, 'second') # 在第二個位置加入'second'字符
-
lb.delete( 2) # 刪除第二個位置的字符
-
lb.pack()
-
-
# 第8步,主窗口循環顯示
-
window.mainloop()
測試效果:
6. Radiobutton窗口部件
簡單說明:
Radiobutton:代表一個變量,它可以有多個值中的一個。點擊它將為這個變量設置值,並且清除與這同一變量相關的其它radiobutton。
什么時候用:
在有一個很多內容選項組成的選項列表提供用戶選擇時會用到,用戶一次只能選擇其中一個,不能多選。
示例代碼:
-
#!/usr/bin/env python
-
# -*- coding: utf-8 -*-
-
# author:洪衛
-
-
import tkinter as tk # 使用Tkinter前需要先導入
-
-
# 第1步,實例化object,建立窗口window
-
window = tk.Tk()
-
-
# 第2步,給窗口的可視化起名字
-
window.title( 'My Window')
-
-
# 第3步,設定窗口的大小(長 * 寬)
-
window.geometry( '500x300') # 這里的乘是小x
-
-
# 第4步,在圖形界面上創建一個標簽label用以顯示並放置
-
var = tk.StringVar() # 定義一個var用來將radiobutton的值和Label的值聯系在一起.
-
l = tk.Label(window, bg= 'yellow', width=20, text='empty')
-
l.pack()
-
-
# 第6步,定義選項觸發函數功能
-
def print_selection():
-
l.config(text= 'you have selected ' + var.get())
-
-
# 第5步,創建三個radiobutton選項,其中variable=var, value='A'的意思就是,當我們鼠標選中了其中一個選項,把value的值A放到變量var中,然后賦值給variable
-
r1 = tk.Radiobutton(window, text= 'Option A', variable=var, value='A', command=print_selection)
-
r1.pack()
-
r2 = tk.Radiobutton(window, text= 'Option B', variable=var, value='B', command=print_selection)
-
r2.pack()
-
r3 = tk.Radiobutton(window, text= 'Option C', variable=var, value='C', command=print_selection)
-
r3.pack()
-
-
# 第7步,主窗口循環顯示
-
window.mainloop()
測試效果:
7. Checkbutton窗口部件
簡單說明:
Checkbutton:代表一個變量,它有兩個不同的值。點擊這個按鈕將會在這兩個值間切換,選擇和取消選擇。
什么時候用:
在有一個很多內容選項組成的選項列表提供用戶選擇時會用到,用戶一次可以選擇多個。
示例代碼:
-
#!/usr/bin/env python
-
# -*- coding: utf-8 -*-
-
# author:洪衛
-
-
import tkinter as tk # 使用Tkinter前需要先導入
-
-
# 第1步,實例化object,建立窗口window
-
window = tk.Tk()
-
-
# 第2步,給窗口的可視化起名字
-
window.title( 'My Window')
-
-
# 第3步,設定窗口的大小(長 * 寬)
-
window.geometry( '500x300') # 這里的乘是小x
-
-
# 第4步,在圖形界面上創建一個標簽label用以顯示並放置
-
l = tk.Label(window, bg= 'yellow', width=20, text='empty')
-
l.pack()
-
-
# 第6步,定義觸發函數功能
-
def print_selection():
-
if (var1.get() == 1) & (var2.get() == 0): # 如果選中第一個選項,未選中第二個選項
-
l.config(text= 'I love only Python ')
-
elif (var1.get() == 0) & (var2.get() == 1): # 如果選中第二個選項,未選中第一個選項
-
l.config(text= 'I love only C++')
-
elif (var1.get() == 0) & (var2.get() == 0): # 如果兩個選項都未選中
-
l.config(text= 'I do not love either')
-
else:
-
l.config(text= 'I love both') # 如果兩個選項都選中
-
-
# 第5步,定義兩個Checkbutton選項並放置
-
var1 = tk.IntVar() # 定義var1和var2整型變量用來存放選擇行為返回值
-
var2 = tk.IntVar()
-
c1 = tk.Checkbutton(window, text= 'Python',variable=var1, onvalue=1, offvalue=0, command=print_selection) # 傳值原理類似於radiobutton部件
-
c1.pack()
-
c2 = tk.Checkbutton(window, text= 'C++',variable=var2, onvalue=1, offvalue=0, command=print_selection)
-
c2.pack()
-
-
# 第7步,主窗口循環顯示
-
window.mainloop()
測試效果:
8. Scale窗口部件
簡單說明:
Scale: 尺度(拉動條),允許你通過滑塊來設置一數字值。
什么時候用:
在需要用戶給出評價等級,或者給出一個評價分數,或者拉動滑動條提供一個具體的數值等等。
示例代碼:
-
#!/usr/bin/env python
-
# -*- coding: utf-8 -*-
-
# author:洪衛
-
-
import tkinter as tk # 使用Tkinter前需要先導入
-
-
# 第1步,實例化object,建立窗口window
-
window = tk.Tk()
-
-
# 第2步,給窗口的可視化起名字
-
window.title( 'My Window')
-
-
# 第3步,設定窗口的大小(長 * 寬)
-
window.geometry( '500x300') # 這里的乘是小x
-
-
# 第4步,在圖形界面上創建一個標簽label用以顯示並放置
-
l = tk.Label(window, bg= 'green', fg='white', width=20, text='empty')
-
l.pack()
-
-
# 第6步,定義一個觸發函數功能
-
def print_selection(v):
-
l.config(text= 'you have selected ' + v)
-
# 第5步,創建一個尺度滑條,長度200字符,從0開始10結束,以2為刻度,精度為0.01,觸發調用print_selection函數
-
s = tk.Scale(window, label= 'try me', from_=0, to=10, orient=tk.HORIZONTAL, length=200, showvalue=0,tickinterval=2, resolution=0.01, command=print_selection)
-
s.pack()
-
-
# 第7步,主窗口循環顯示
-
window.mainloop()
測試效果:
9. Canvas窗口部件
簡單說明:
Canvas:畫布,提供繪圖功能(直線、橢圓、多邊形、矩形) 可以包含圖形或位圖,用來繪制圖表和圖,創建圖形編輯器,實現定制窗口部件。
什么時候用:
在比如像用戶交互界面等,需要提供設計的圖標、圖形、logo等信息是可以用到畫布。
示例代碼:
-
#!/usr/bin/env python
-
# -*- coding: utf-8 -*-
-
# author:洪衛
-
-
import tkinter as tk # 使用Tkinter前需要先導入
-
-
# 第1步,實例化object,建立窗口window
-
window = tk.Tk()
-
-
# 第2步,給窗口的可視化起名字
-
window.title( 'My Window')
-
-
# 第3步,設定窗口的大小(長 * 寬)
-
window.geometry( '500x300') # 這里的乘是小x
-
-
# 第4步,在圖形界面上創建 500 * 200 大小的畫布並放置各種元素
-
canvas = tk.Canvas(window, bg= 'green', height=200, width=500)
-
# 說明圖片位置,並導入圖片到畫布上
-
image_file = tk.PhotoImage(file= 'pic.gif') # 圖片位置(相對路徑,與.py文件同一文件夾下,也可以用絕對路徑,需要給定圖片具體絕對路徑)
-
image = canvas.create_image( 250, 0, anchor='n',image=image_file) # 圖片錨定點(n圖片頂端的中間點位置)放在畫布(250,0)坐標處
-
# 定義多邊形參數,然后在畫布上畫出指定圖形
-
x0, y0, x1, y1 = 100, 100, 150, 150
-
line = canvas.create_line(x0 -50, y0-50, x1-50, y1-50) # 畫直線
-
oval = canvas.create_oval(x0+ 120, y0+50, x1+120, y1+50, fill='yellow') # 畫圓 用黃色填充
-
arc = canvas.create_arc(x0, y0+ 50, x1, y1+50, start=0, extent=180) # 畫扇形 從0度打開收到180度結束
-
rect = canvas.create_rectangle( 330, 30, 330+20, 30+20) # 畫矩形正方形
-
canvas.pack()
-
-
# 第6步,觸發函數,用來一定指定圖形
-
def moveit():
-
canvas.move(rect, 2, 2) # 移動正方形rect(也可以改成其他圖形名字用以移動一起圖形、元素),按每次(x=2, y=2)步長進行移動
-
-
# 第5步,定義一個按鈕用來移動指定圖形的在畫布上的位置
-
b = tk.Button(window, text= 'move item',command=moveit).pack()
-
-
# 第7步,主窗口循環顯示
-
window.mainloop()
所用圖片:
當然你可以隨意用你的一張圖片導入畫布試一試效果,圖片可以用畫圖工具改一下像素大小,以免圖片太大,導入畫布顯示不全,當然你也可以用我提供的素材,下面是鏈接:https://files.cnblogs.com/files/shwee/pic.gif
圖片錨定點位置參數圖:
測試效果:
10. Menu窗口部件
簡單說明:
Menu:菜單條,用來實現下拉和彈出式菜單,點下菜單后彈出的一個選項列表,用戶可以從中選擇
什么時候用:
在比如像軟件或網頁交互界面等,需要提供菜單選項功能提供用戶選擇菜單選項功能時用到。
示例代碼:
-
#!/usr/bin/env python
-
# -*- coding: utf-8 -*-
-
# author:洪衛
-
-
import tkinter as tk # 使用Tkinter前需要先導入
-
-
# 第1步,實例化object,建立窗口window
-
window = tk.Tk()
-
-
# 第2步,給窗口的可視化起名字
-
window.title( 'My Window')
-
-
# 第3步,設定窗口的大小(長 * 寬)
-
window.geometry( '500x300') # 這里的乘是小x
-
-
# 第4步,在圖形界面上創建一個標簽用以顯示內容並放置
-
l = tk.Label(window, text= ' ', bg='green')
-
l.pack()
-
-
# 第10步,定義一個函數功能,用來代表菜單選項的功能,這里為了操作簡單,定義的功能比較簡單
-
counter = 0
-
def do_job():
-
global counter
-
l.config(text= 'do '+ str(counter))
-
counter += 1
-
-
# 第5步,創建一個菜單欄,這里我們可以把他理解成一個容器,在窗口的上方
-
menubar = tk.Menu(window)
-
-
# 第6步,創建一個File菜單項(默認不下拉,下拉內容包括New,Open,Save,Exit功能項)
-
filemenu = tk.Menu(menubar, tearoff= 0)
-
# 將上面定義的空菜單命名為File,放在菜單欄中,就是裝入那個容器中
-
menubar.add_cascade(label= 'File', menu=filemenu)
-
-
# 在File中加入New、Open、Save等小菜單,即我們平時看到的下拉菜單,每一個小菜單對應命令操作。
-
filemenu.add_command(label= 'New', command=do_job)
-
filemenu.add_command(label= 'Open', command=do_job)
-
filemenu.add_command(label= 'Save', command=do_job)
-
filemenu.add_separator() # 添加一條分隔線
-
filemenu.add_command(label= 'Exit', command=window.quit) # 用tkinter里面自帶的quit()函數
-
-
# 第7步,創建一個Edit菜單項(默認不下拉,下拉內容包括Cut,Copy,Paste功能項)
-
editmenu = tk.Menu(menubar, tearoff= 0)
-
# 將上面定義的空菜單命名為 Edit,放在菜單欄中,就是裝入那個容器中
-
menubar.add_cascade(label= 'Edit', menu=editmenu)
-
-
# 同樣的在 Edit 中加入Cut、Copy、Paste等小命令功能單元,如果點擊這些單元, 就會觸發do_job的功能
-
editmenu.add_command(label= 'Cut', command=do_job)
-
editmenu.add_command(label= 'Copy', command=do_job)
-
editmenu.add_command(label= 'Paste', command=do_job)
-
-
# 第8步,創建第二級菜單,即菜單項里面的菜單
-
submenu = tk.Menu(filemenu) # 和上面定義菜單一樣,不過此處實在File上創建一個空的菜單
-
filemenu.add_cascade(label= 'Import', menu=submenu, underline=0) # 給放入的菜單submenu命名為Import
-
-
# 第9步,創建第三級菜單命令,即菜單項里面的菜單項里面的菜單命令(有點拗口,笑~~~)
-
submenu.add_command(label= 'Submenu_1', command=do_job) # 這里和上面創建原理也一樣,在Import菜單項中加入一個小菜單命令Submenu_1
-
-
# 第11步,創建菜單欄完成后,配置讓菜單欄menubar顯示出來
-
window.config(menu=menubar)
-
-
# 第12步,主窗口循環顯示
-
window.mainloop()
測試效果:
11. Frame 窗口部件
簡單說明:
Frame:框架,用來承載放置其他GUI元素,就是一個容器,是一個在 Windows 上分離小區域的部件, 它能將 Windows 分成不同的區,然后存放不同的其他部件. 同時一個 Frame 上也能再分成兩個 Frame, Frame 可以認為是一種容器.
什么時候用:
在比如像軟件或網頁交互界面等,有不同的界面邏輯層級和功能區域划分時可以用到,讓交互界面邏輯更加清晰。
示例代碼:
-
#!/usr/bin/env python
-
# -*- coding: utf-8 -*-
-
# author:洪衛
-
-
import tkinter as tk # 使用Tkinter前需要先導入
-
-
# 第1步,實例化object,建立窗口window
-
window = tk.Tk()
-
-
# 第2步,給窗口的可視化起名字
-
window.title( 'My Window')
-
-
# 第3步,設定窗口的大小(長 * 寬)
-
window.geometry( '500x300') # 這里的乘是小x
-
-
# 第4步,在圖形界面上創建一個標簽用以顯示內容並放置
-
tk.Label(window, text= 'on the window', bg='red', font=('Arial', 16)).pack() # 和前面部件分開創建和放置不同,其實可以創建和放置一步完成
-
-
# 第5步,創建一個主frame,長在主window窗口上
-
frame = tk.Frame(window)
-
frame.pack()
-
-
# 第6步,創建第二層框架frame,長在主框架frame上面
-
frame_l = tk.Frame(frame) # 第二層frame,左frame,長在主frame上
-
frame_r = tk.Frame(frame) # 第二層frame,右frame,長在主frame上
-
frame_l.pack(side= 'left')
-
frame_r.pack(side= 'right')
-
-
# 第7步,創建三組標簽,為第二層frame上面的內容,分為左區域和右區域,用不同顏色標識
-
tk.Label(frame_l, text= 'on the frame_l1', bg='green').pack()
-
tk.Label(frame_l, text= 'on the frame_l2', bg='green').pack()
-
tk.Label(frame_l, text= 'on the frame_l3', bg='green').pack()
-
tk.Label(frame_r, text= 'on the frame_r1', bg='yellow').pack()
-
tk.Label(frame_r, text= 'on the frame_r2', bg='yellow').pack()
-
tk.Label(frame_r, text= 'on the frame_r3', bg='yellow').pack()
-
-
# 第8步,主窗口循環顯示
-
window.mainloop()
測試效果:
12. messageBox窗口部件
簡單說明:
messageBox:消息框,用於顯示你應用程序的消息框。(Python2中為tkMessagebox),其實這里的messageBox就是我們平時看到的彈窗。 我們首先需要定義一個觸發功能,來觸發這個彈窗,這里我們就放上以前學過的button按鈕,通過觸發功能,調用messagebox吧,點擊button按鈕就會彈出提示對話框。下面給出messagebox提示信息的幾種形式:
-
tkinter.messagebox.showinfo(title= 'Hi', message='你好!') # 提示信息對話窗
-
tkinter.messagebox.showwarning(title= 'Hi', message='有警告!') # 提出警告對話窗
-
tkinter.messagebox.showerror(title= 'Hi', message='出錯了!') # 提出錯誤對話窗
-
print(tkinter.messagebox.askquestion(title= 'Hi', message='你好!')) # 詢問選擇對話窗return 'yes', 'no'
-
print(tkinter.messagebox.askyesno(title= 'Hi', message='你好!')) # return 'True', 'False'
-
print(tkinter.messagebox.askokcancel(title= 'Hi', message='你好!')) # return 'True', 'False'
什么時候用:
在比如像軟件或網頁交互界面等,有不同的界面邏輯層級和功能區域划分時可以用到,讓交互界面邏輯更加清晰。
示例代碼:
-
#!/usr/bin/env python
-
# -*- coding: utf-8 -*-
-
# author:洪衛
-
-
import tkinter as tk # 使用Tkinter前需要先導入
-
import tkinter.messagebox # 要使用messagebox先要導入模塊
-
-
# 第1步,實例化object,建立窗口window
-
window = tk.Tk()
-
-
# 第2步,給窗口的可視化起名字
-
window.title( 'My Window')
-
-
# 第3步,設定窗口的大小(長 * 寬)
-
window.geometry( '500x300') # 這里的乘是小x
-
-
# 第5步,定義觸發函數功能
-
def hit_me():
-
tkinter.messagebox.showinfo(title= 'Hi', message='你好!') # 提示信息對話窗
-
# tkinter.messagebox.showwarning(title='Hi', message='有警告!') # 提出警告對話窗
-
# tkinter.messagebox.showerror(title='Hi', message='出錯了!') # 提出錯誤對話窗
-
# print(tkinter.messagebox.askquestion(title='Hi', message='你好!')) # 詢問選擇對話窗return 'yes', 'no'
-
# print(tkinter.messagebox.askyesno(title='Hi', message='你好!')) # return 'True', 'False'
-
# print(tkinter.messagebox.askokcancel(title='Hi', message='你好!')) # return 'True', 'False'
-
-
# 第4步,在圖形界面上創建一個標簽用以顯示內容並放置
-
tk.Button(window, text= 'hit me', bg='green', font=('Arial', 14), command=hit_me).pack()
-
-
# 第6步,主窗口循環顯示
-
window.mainloop()
測試效果:
13. 窗口部件三種放置方式pack/grid/place
參考來源:
The Grid Geometry Manager
The Pack Geometry Manager
The Place Geometry Manager
1. Grid:The Grid Geometry Manager
grid 是方格, 所以所有的內容會被放在這些規律的方格中。例如:
-
for i in range(3):
-
for j in range(3):
-
tk.Label(window, text= 1).grid(row=i, column=j, padx=10, pady=10, ipadx=10, ipady=10)
以上的代碼就是創建一個三行三列的表格,其實 grid 就是用表格的形式定位的。這里的參數 row 為行,colum 為列,padx 就是單元格左右間距,pady 就是單元格上下間距,ipadx是單元格內部元素與單元格的左右間距,ipady是單元格內部元素與單元格的上下間距。
示例代碼:
-
#!/usr/bin/env python
-
# -*- coding: utf-8 -*-
-
# author:洪衛
-
-
import tkinter as tk # 使用Tkinter前需要先導入
-
-
# 第1步,實例化object,建立窗口window
-
window = tk.Tk()
-
-
# 第2步,給窗口的可視化起名字
-
window.title( 'My Window')
-
-
# 第3步,設定窗口的大小(長 * 寬)
-
window.geometry( '500x300') # 這里的乘是小x
-
-
# 第4步,grid 放置方法
-
for i in range(3):
-
for j in range(3):
-
tk.Label(window, text= 1).grid(row=i, column=j, padx=10, pady=10, ipadx=10, ipady=10)
-
-
# 第5步,主窗口循環顯示
-
window.mainloop()
測試效果:
2. Pack:The Pack Geometry Manager
我們常用的pack(), 他會按照上下左右的方式排列.例如:
-
tk.Label(window, text= 'P', fg='red').pack(side='top') # 上
-
tk.Label(window, text= 'P', fg='red').pack(side='bottom') # 下
-
tk.Label(window, text= 'P', fg='red').pack(side='left') # 左
-
tk.Label(window, text= 'P', fg='red').pack(side='right') # 右
示例代碼:
-
#!/usr/bin/env python
-
# -*- coding: utf-8 -*-
-
# author:洪衛
-
-
import tkinter as tk # 使用Tkinter前需要先導入
-
-
# 第1步,實例化object,建立窗口window
-
window = tk.Tk()
-
-
# 第2步,給窗口的可視化起名字
-
window.title( 'My Window')
-
-
# 第3步,設定窗口的大小(長 * 寬)
-
window.geometry( '500x300') # 這里的乘是小x
-
-
# 第4步,pack 放置方法
-
tk.Label(window, text= 'P', fg='red').pack(side='top') # 上
-
tk.Label(window, text= 'P', fg='red').pack(side='bottom') # 下
-
tk.Label(window, text= 'P', fg='red').pack(side='left') # 左
-
tk.Label(window, text= 'P', fg='red').pack(side='right') # 右
-
-
# 第5步,主窗口循環顯示
-
window.mainloop()
測試效果:
3. Place:The Place Geometry Manager
再接下來我們來看place(), 這個比較容易理解,就是給精確的坐標來定位,如此處給的(50, 100),就是將這個部件放在坐標為(x=50, y=100)的這個位置, 后面的參數 anchor='nw',就是前面所講的錨定點是西北角。例如:
tk.Label(window, text='Pl', font=('Arial', 20), ).place(x=50, y=100, anchor='nw')
示例代碼:
-
#!/usr/bin/env python
-
# -*- coding: utf-8 -*-
-
# author:洪衛
-
-
import tkinter as tk # 使用Tkinter前需要先導入
-
-
# 第1步,實例化object,建立窗口window
-
window = tk.Tk()
-
-
# 第2步,給窗口的可視化起名字
-
window.title( 'My Window')
-
-
# 第3步,設定窗口的大小(長 * 寬)
-
window.geometry( '500x300') # 這里的乘是小x
-
-
# 第4步,place 放置方法(精准的放置到指定坐標點的位置上)
-
tk.Label(window, text= 'Pl', font=('Arial', 20), ).place(x=50, y=100, anchor='nw')
-
-
# 第5步,主窗口循環顯示
-
window.mainloop()
測試效果:
14. 綜合練習,用戶登錄窗口例子
編寫一個用戶登錄界面,用戶可以登錄賬戶信息,如果賬戶已經存在,可以直接登錄,登錄名或者登錄密碼輸入錯誤會提示,如果賬戶不存在,提示用戶注冊,點擊注冊進去注冊頁面,輸入注冊信息,確定后便可以返回登錄界面進行登錄。
示例代碼:
-
#!/usr/bin/env python
-
# -*- coding: utf-8 -*-
-
# author:洪衛
-
-
import tkinter as tk # 使用Tkinter前需要先導入
-
import tkinter.messagebox
-
import pickle
-
-
# 第1步,實例化object,建立窗口window
-
window = tk.Tk()
-
-
# 第2步,給窗口的可視化起名字
-
window.title( 'Wellcome to Hongwei Website')
-
-
# 第3步,設定窗口的大小(長 * 寬)
-
window.geometry( '400x300') # 這里的乘是小x
-
-
# 第4步,加載 wellcome image
-
canvas = tk.Canvas(window, width= 400, height=135, bg='green')
-
image_file = tk.PhotoImage(file= 'pic.gif')
-
image = canvas.create_image( 200, 0, anchor='n', image=image_file)
-
canvas.pack(side= 'top')
-
tk.Label(window, text= 'Wellcome',font=('Arial', 16)).pack()
-
-
# 第5步,用戶信息
-
tk.Label(window, text= 'User name:', font=('Arial', 14)).place(x=10, y=170)
-
tk.Label(window, text= 'Password:', font=('Arial', 14)).place(x=10, y=210)
-
-
# 第6步,用戶登錄輸入框entry
-
# 用戶名
-
var_usr_name = tk.StringVar()
-
var_usr_name.set( 'example@python.com')
-
entry_usr_name = tk.Entry(window, textvariable=var_usr_name, font=( 'Arial', 14))
-
entry_usr_name.place(x= 120,y=175)
-
# 用戶密碼
-
var_usr_pwd = tk.StringVar()
-
entry_usr_pwd = tk.Entry(window, textvariable=var_usr_pwd, font=( 'Arial', 14), show='*')
-
entry_usr_pwd.place(x= 120,y=215)
-
-
# 第8步,定義用戶登錄功能
-
def usr_login():
-
# 這兩行代碼就是獲取用戶輸入的usr_name和usr_pwd
-
usr_name = var_usr_name.get()
-
usr_pwd = var_usr_pwd.get()
-
-
# 這里設置異常捕獲,當我們第一次訪問用戶信息文件時是不存在的,所以這里設置異常捕獲。
-
# 中間的兩行就是我們的匹配,即程序將輸入的信息和文件中的信息匹配。
-
try:
-
with open('usrs_info.pickle', 'rb') as usr_file:
-
usrs_info = pickle.load(usr_file)
-
except FileNotFoundError:
-
# 這里就是我們在沒有讀取到`usr_file`的時候,程序會創建一個`usr_file`這個文件,並將管理員
-
# 的用戶和密碼寫入,即用戶名為`admin`密碼為`admin`。
-
with open('usrs_info.pickle', 'wb') as usr_file:
-
usrs_info = { 'admin': 'admin'}
-
pickle.dump(usrs_info, usr_file)
-
usr_file.close() # 必須先關閉,否則pickle.load()會出現EOFError: Ran out of input
-
-
# 如果用戶名和密碼與文件中的匹配成功,則會登錄成功,並跳出彈窗how are you? 加上你的用戶名。
-
if usr_name in usrs_info:
-
if usr_pwd == usrs_info[usr_name]:
-
tkinter.messagebox.showinfo(title= 'Welcome', message='How are you? ' + usr_name)
-
# 如果用戶名匹配成功,而密碼輸入錯誤,則會彈出'Error, your password is wrong, try again.'
-
else:
-
tkinter.messagebox.showerror(message= 'Error, your password is wrong, try again.')
-
else: # 如果發現用戶名不存在
-
is_sign_up = tkinter.messagebox.askyesno( 'Welcome! ', 'You have not sign up yet. Sign up now?')
-
# 提示需不需要注冊新用戶
-
if is_sign_up:
-
usr_sign_up()
-
-
# 第9步,定義用戶注冊功能
-
def usr_sign_up():
-
def sign_to_Hongwei_Website():
-
# 以下三行就是獲取我們注冊時所輸入的信息
-
np = new_pwd.get()
-
npf = new_pwd_confirm.get()
-
nn = new_name.get()
-
-
# 這里是打開我們記錄數據的文件,將注冊信息讀出
-
with open('usrs_info.pickle', 'rb') as usr_file:
-
exist_usr_info = pickle.load(usr_file)
-
# 這里就是判斷,如果兩次密碼輸入不一致,則提示Error, Password and confirm password must be the same!
-
if np != npf:
-
tkinter.messagebox.showerror( 'Error', 'Password and confirm password must be the same!')
-
-
# 如果用戶名已經在我們的數據文件中,則提示Error, The user has already signed up!
-
elif nn in exist_usr_info:
-
tkinter.messagebox.showerror( 'Error', 'The user has already signed up!')
-
-
# 最后如果輸入無以上錯誤,則將注冊輸入的信息記錄到文件當中,並提示注冊成功Welcome!,You have successfully signed up!,然后銷毀窗口。
-
else:
-
exist_usr_info[nn] = np
-
with open('usrs_info.pickle', 'wb') as usr_file:
-
pickle.dump(exist_usr_info, usr_file)
-
tkinter.messagebox.showinfo( 'Welcome', 'You have successfully signed up!')
-
# 然后銷毀窗口。
-
window_sign_up.destroy()
-
-
# 定義長在窗口上的窗口
-
window_sign_up = tk.Toplevel(window)
-
window_sign_up.geometry( '300x200')
-
window_sign_up.title( 'Sign up window')
-
-
new_name = tk.StringVar() # 將輸入的注冊名賦值給變量
-
new_name.set( 'example@python.com') # 將最初顯示定為'example@python.com'
-
tk.Label(window_sign_up, text= 'User name: ').place(x=10, y=10) # 將`User name:`放置在坐標(10,10)。
-
entry_new_name = tk.Entry(window_sign_up, textvariable=new_name) # 創建一個注冊名的`entry`,變量為`new_name`
-
entry_new_name.place(x= 130, y=10) # `entry`放置在坐標(150,10).
-
-
new_pwd = tk.StringVar()
-
tk.Label(window_sign_up, text= 'Password: ').place(x=10, y=50)
-
entry_usr_pwd = tk.Entry(window_sign_up, textvariable=new_pwd, show= '*')
-
entry_usr_pwd.place(x= 130, y=50)
-
-
new_pwd_confirm = tk.StringVar()
-
tk.Label(window_sign_up, text= 'Confirm password: ').place(x=10, y=90)
-
entry_usr_pwd_confirm = tk.Entry(window_sign_up, textvariable=new_pwd_confirm, show= '*')
-
entry_usr_pwd_confirm.place(x= 130, y=90)
-
-
# 下面的 sign_to_Hongwei_Website
-
btn_comfirm_sign_up = tk.Button(window_sign_up, text= 'Sign up', command=sign_to_Hongwei_Website)
-
btn_comfirm_sign_up.place(x= 180, y=120)
-
-
# 第7步,login and sign up 按鈕
-
btn_login = tk.Button(window, text= 'Login', command=usr_login)
-
btn_login.place(x= 120, y=240)
-
btn_sign_up = tk.Button(window, text= 'Sign up', command=usr_sign_up)
-
btn_sign_up.place(x= 200, y=240)
-
-
# 第10步,主窗口循環顯示
-
window.mainloop()
測試效果:
15. 其他部件后續再補充...
注:不同電腦可能配置環境略有不同,如有小錯誤可以自己調試一下。