關於Tkinter
Tkinter 模塊(Tk 接口)是 Python 的標准 Tk GUI 工具包的接口 .Tk 和 Tkinter 可以在大多數的 Unix 平台下使用,同樣可以應用在 Windows 和 Macintosh 系統里。Tk8.0 的后續版本可以實現本地窗口風格,並良好地運行在絕大多數平台中。
Tkinter模塊("Tk 接口")是Python的標准Tk GUI工具包的接口。作為 python 特定的GUI界面,是一個圖像的窗口,tkinter是python 自帶的,可以編輯的GUI界面,我們可以用GUI 實現很多直觀的功能,比如想開發一個計算器,如果只是一個程序輸入,輸出窗口的話,是沒用用戶體驗的。所有開發一個圖像化的小窗口,就是必要的。
對於稍有GUI編程經驗的人來說,Python的Tkinter界面庫是非常簡單的。python的GUI庫非常多,選擇Tkinter,一是最為簡單,二是自帶庫,不需下載安裝,隨時使用,三則是從需求出發,Python作為一種腳本語言,一種膠水語言,一般不會用它來開發復雜的桌面應用,它並不具備這方面的優勢,使用Python,可以把它作為一個靈活的工具,而不是作為主要開發語言,那么在工作中,需要制作一個小工具,肯定是需要有界面的,不僅自己用,也能分享別人使用,在這種需求下,Tkinter是足夠勝任的!
Tkinter 編程
Tkinter 是 Python 的標准 GUI 庫。Python 使用 Tkinter 可以快速的創建 GUI 應用程序。
由於 Tkinter 是內置到 python 的安裝包中、只要安裝好 Python 之后就能 import Tkinter 庫、而且 IDLE 也是用 Tkinter 編寫而成、對於簡單的圖形界面 Tkinter 還是能應付自如。
import tkinter
Tkinter 組件
Tkinter的提供各種控件,如按鈕,標簽和文本框,一個GUI應用程序中使用。這些控件通常被稱為控件或者部件。
目前有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 | 用於顯示你應用程序的消息框。 |
標准屬性
標准屬性也就是所有控件的共同屬性,如大小,字體和顏色等等。
屬性 | 描述 |
Dimension | 控件大小; |
Color | 控件顏色; |
Font | 控件字體; |
Anchor | 錨點; |
Relief | 控件樣式; |
Bitmap | 位圖; |
Cursor | 光標; |
實踐1:制作一個BMI 計算器GUI程序
編寫一個簡單的界面,用戶輸入體重、身高,點擊計算按鈕,生成身體質量指數,簡稱體質數
示例代碼
#!/usr/bin/env python3 # -*- coding:utf-8 -*- import tkinter as tk from tkinter import ttk # 主體控件命名模塊 class BMIView(tk.Frame): def __init__(self,parent,*args,**kwargs): super().__init__(parent,*args,**kwargs) # parent 指的是當前這個控件容器將會依附在哪個容器或者窗體之上 self.body_weight = tk.DoubleVar() self.height = tk.DoubleVar() self.bmi = tk.StringVar() lbl_body_weight = ttk.Label(self,text="體重(Kg):") entry_body_weight = ttk.Entry(self,textvariable=self.body_weight) lbl_height = ttk.Label(self,text="身高(m):") entry_height = ttk.Entry(self,textvariable=self.height) btn_calculate = ttk.Button(self,text="計算",command=self.on_calculate) lbl_bmi = ttk.Label(self,textvariable=self.bmi,font=("Microsoft Yahei",64),wraplength=480) lbl_body_weight.grid(row=0,column=0,sticky=tk.W) entry_body_weight.grid(row=0,column=1,sticky=(tk.W+tk.E)) lbl_height.grid(row=0,column=2,sticky=(tk.W+tk.E)) entry_height.grid(row=0,column=3,sticky=(tk.W+tk.E)) btn_calculate.grid(row=0,column=4,sticky=(tk.E)) lbl_bmi.grid(row=1,column=0,columnspan=5) # columnspan=5 合並5個單元格 self.columnconfigure(1,weight=1) self.columnconfigure(3,weight=1) def on_calculate(self): bmi = self.body_weight.get() / (self.height.get() ** 2) print('bmi:',bmi) self.bmi.set(f"{bmi:.1f}") class BMIApplication(tk.Tk): def __init__(self,*args,**kwargs): super().__init__(*args,**kwargs) self.title("BMI 計算器") self.geometry("640x180") self.resizable(width=False,height=False) BMIView(self).grid(sticky=(tk.E+tk.N+tk.W+tk.S)) self.columnconfigure(0,weight=1) if __name__ == '__main__': app = BMIApplication() app.mainloop()
測試功能:
實踐2:制作一個簡單登錄的GUI程序
輸入用戶名、密碼,點擊登錄
AC1:輸入正確用戶名、密碼,點擊登錄,彈窗提示登錄成功
AC2:輸入錯誤用戶名或密碼,點擊登錄,彈窗提示登錄異常
# !/usr/bin/env python3 # -*- coding:utf-8 -*- """使用Entry組件的基本用法,使用面向對象的方式""" import tkinter as tk from tkinter import messagebox class Application(tk.Frame): def __init__(self,master=None): super().__init__(master) # super()代表的是父類的定義,而不是父類對象 self.master = master self.pack() self.createWidget() def createWidget(self): global photo # 把photo聲明成全局變量。如果是局部變量,本方法執行完畢后,圖像對象銷毀,窗口顯示不出來 photo = tk.PhotoImage(file="imge/logo.png") self.label03 = tk.Label(self, image=photo) self.label03.pack() """創建界面登錄的組件""" self.label01 = tk.Label(self,text="用戶名") self.label01.pack() # StringVar變量綁定到指定組件 # StringVar變量的值發生變化,組件內容也變化 # 組件內容發生變化,StringVar變量的值也發生變化 v1 = tk.StringVar() self.entry01 = tk.Entry(self,textvariable=v1) self.entry01.pack() v1.set("admin") """創建密碼框""" self.label02 = tk.Label(self, text="密碼") self.label02.pack() v2 = tk.StringVar() self.entry02 = tk.Entry(self, textvariable=v2,show="*") self.entry02.pack() self.btn01 = tk.Button(self, text="登錄", command=self.login) self.btn01.pack() def login(self): username = self.entry01.get() pwd = self.entry02.get() if username == "admin" and pwd == "123456": messagebox.showinfo("登錄系統","登錄成功!歡迎開始學習!") else: messagebox.showinfo("登錄系統", "賬號或密碼錯誤,請重新輸入") root = tk.Tk() root.geometry("400x300+600+400") root.title("測試Entry") app = Application(master=root) if __name__ == '__main__': root.mainloop()
實踐3:操作TEXT的GUI程序
# !/usr/bin/env python3 # -*- coding:utf-8 -*- """使用Text組件的基本用法,使用面向對象的方式""" import tkinter as tk import webbrowser class Application(tk.Frame): def __init__(self,master=None): super().__init__(master) # super()代表的是父類的定義,而不是父類對象 self.master = master self.pack() self.createWidget() def createWidget(self): self.w1 = tk.Text(root,width=40,height=12,bg="gray") # 寬度20個字母(10個漢字),高度一個行高 self.w1.pack() self.w1.insert(1.0,"0123456789\nabcdefghijklmn") self.w1.insert(2.3,"鋤禾日當午,汗滴禾下土,誰知盤中餐,粒粒皆辛苦\n") tk.Button(self,text="重復插入文本",command=self.insertText).pack(side="left") tk.Button(self,text="返回文本",command=self.returnText).pack(side="left") tk.Button(self,text="添加圖片",command=self.addImage).pack(side="left") tk.Button(self,text="添加組件",command=self.addWidget).pack(side="left") tk.Button(self,text="通過tag精確控制文本",command=self.testTag).pack(side="left") def insertText(self): # INSERT索引表示在光標處插入 self.w1.insert(tk.INSERT,' test ') # END索引表示在最后插入 self.w1.insert(tk.END,'[sxt]') def returnText(self): # Indexes(索引)是用來指向Text組件中文本的位置,Text的組件索引也是對應實際字符之間得位置 # 核心:行號以1開始,列號以0開始 print(self.w1.get(1.2,1.6)) self.w1.insert(1.8," test2 ") print("所有文本內容:\n"+self.w1.get(1.0,tk.END)) def addImage(self): self.photo = tk.PhotoImage(file="imge/logo.png") self.w1.image_create(tk.END,image=self.photo) def addWidget(self): b1 = tk.Button(self.w1,text="測試TEXT") # 在text創建組件的命令 self.w1.window_create(tk.INSERT,window=b1) def testTag(self): self.w1.delete(1.0,tk.END) self.w1.insert(tk.INSERT,"good good study,day day up!\n前端開發\n后端開發\n測試設計") self.w1.tag_add("good",1.0,1.9) self.w1.tag_config("good",background="yellow",foreground="red") self.w1.tag_add("baidu",4.0,4.2) self.w1.tag_config("baidu",underline=True) self.w1.tag_bind("baidu","<Button-1>",self.webshow) def webshow(self,event): webbrowser.open("https://www.baidu.com") root = tk.Tk() root.geometry("500x250+600+400") root.title("測試TEXT") app = Application(master=root) if __name__ == '__main__': root.mainloop()