今天繼續測試 tkinter 的 Entry 元件, 本系列之前的文章參考 :
# Python 內建 GUI 模組 tkinter 測試 (一) : 建立視窗
# Python 內建 GUI 模組 tkinter 測試 (二) : 對話框
# Python 內建 GUI 模組 tkinter 測試 (三) : 版面管理員
Entry 元件用來輸入單行文字, 亦即換行字元在此元件中是無效的. 其語法如下 :
Entry(父容器, **參數列)
參考 :
Entry 元件常用參數如下表 :
Entry 元件常用屬性 | 說明 |
textvariable | 動態綁定文字欄位內容的類別變數物件名稱 |
show | 輸入資料時顯示的固定字元, 例如用於密碼欄位 |
width | 寬度 (單位=字元數) |
height | 高度 (單位=字元數) |
bg/background | 背景色, 可用標準顏色名稱字串例如 'blue' 或 "#0000ff" |
fg/foreground | 前景色 (文字顏色), 可用標準顏色名稱字串例如 'blue' 或 "#0000ff" |
font | 設定字型與尺寸 (px), 粗體 (bold) 或斜體 (italic), 底線或刪除線等 |
padx | 元件與容器的水平間距 (px) |
pady | 元件與容器的垂直間距 (px) |
state | 設定按鈕狀態=tk.NORMAL (預設可用)/tk.DISABLED (不可用) |
對於 Entry 元件而言, 最重要的參數是動態綁定其內容值的 textvariable, 可透過 StringVar, IntVar, DoubleVar, BoolVar 這四種類別變數的 set() 與 get() 來存取其內容. 例如下面這個 tk 的四則運算器範例 :
測試 1 : 四則運算器 (tk) [看原始碼]
import tkinter as tk
from tkinter import ttk
def add():
c.set(a.get() + b.get())
def sub():
c.set(a.get() - b.get())
def mul():
c.set(a.get() * b.get())
def div():
if b.get() != 0: //取得類別變數 (除數) 之值
c.set(a.get() / b.get()) //除數不為 0 才除
else:
c.set(float("inf")) //除以 0 顯示為無窮大
win=tk.Tk()
win.title("tkinter GUI 測試")
win.geometry("500x200")
a=tk.DoubleVar()
b=tk.DoubleVar()
c=tk.DoubleVar()
tk.Entry(win, width=10, textvariable=a).grid(row=0, column=0) //輸入運算元 a
tk.Label(text="+", width=5).grid(row=0, column=1)
tk.Entry(win, width=10, textvariable=b).grid(row=0, column=2) //輸入運算元 b
tk.Button(win, text="=", width=5, command=add).grid(row=0, column=3) //加法按鈕
tk.Entry(win, width=10, textvariable=c).grid(row=0, column=4) //儲存運算結果 c
tk.Label(win, text="-", width=5).grid(row=1, column=1)
tk.Button(win, text="=", width=5, command=sub).grid(row=1, column=3) //減法按鈕
tk.Label(win, text="*", width=5).grid(row=2, column=1)
tk.Button(win, text="=", width=5, command=mul).grid(row=2, column=3) //乘法按鈕
tk.Label(win, text="/", width=5).grid(row=3, column=1)
tk.Button(win, text="=", width=5, command=div).grid(row=3, column=3) //除法按鈕
win.mainloop()
此例定義了 a, b, c 三個 DoubleVar 類別變數分別與三個 Entry 元件綁定, 並使用 grid 排版來放置 Label, Entry, 以及 Button 元件, 當按下 +, -, *, / 相對應的 = 按鈕就會在第三個 Entry 元件上顯示四則運算之值, 其中除法需要特別處理除數為 0 的情況, 結果如下 :
下面是上例的 ttk 版本, 只是將建立元件的 tk 改成 ttk 而已 :
測試 2 : 四則運算器 (ttk) [看原始碼]
import tkinter as tk
from tkinter import ttk
def add():
c.set(a.get() + b.get())
def sub():
c.set(a.get() - b.get())
def mul():
c.set(a.get() * b.get())
def div():
if b.get() != 0:
c.set(a.get() / b.get())
else:
c.set(float("inf"))
win=tk.Tk()
win.title("tkinter GUI 測試")
win.geometry("500x200")
a=tk.DoubleVar()
b=tk.DoubleVar()
c=tk.DoubleVar()
ttk.Entry(win, width=10, textvariable=a).grid(row=0, column=0)
ttk.Label(text="+", width=5).grid(row=0, column=1)
ttk.Entry(win, width=10, textvariable=b).grid(row=0, column=2)
ttk.Button(text="=", width=5, command=add).grid(row=0, column=3)
ttk.Entry(win, width=10, textvariable=c).grid(row=0, column=4)
ttk.Label(text="-", width=5).grid(row=1, column=1)
ttk.Button(text="=", width=5, command=sub).grid(row=1, column=3)
ttk.Label(text="*", width=5).grid(row=2, column=1)
ttk.Button(text="=", width=5, command=mul).grid(row=2, column=3)
ttk.Label(text="/", width=5).grid(row=3, column=1)
ttk.Button(text="=", width=5, command=div).grid(row=3, column=3)
win.mainloop()
結果如下 :
下面是模擬登入頁面的範例 :
測試 3 : tk 模擬登入頁面 [看原始碼]
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox as msgbox
def clear():
account.set("")
pwd.set("")
def login():
if account.get() == "admin" and pwd.get() == "admin":
msgbox.showinfo("Info", "登入成功")
else:
msgbox.showinfo("Info", "帳號或密碼錯誤")
win=tk.Tk()
win.title("tkinter GUI 測試")
win.geometry("300x150")
account=tk.StringVar()
pwd=tk.StringVar()
tk.Label(win, text="帳號").grid(row=0, column=0)
tk.Entry(win, textvariable=account).grid(row=0, column=1)
tk.Label(win, text="密碼").grid(row=1, column=0)
tk.Entry(win, textvariable=pwd).grid(row=1, column=1)
tk.Button(text="清除", command=clear).grid(row=2, column=0)
tk.Button(text="登入", command=login).grid(row=2, column=1)
win.mainloop()
此例中的兩個 Entry 用來收集使用者輸入之帳號密碼, 用 textvariable 參數分別綁定到 account 與 pwd 這兩個 StringVar 類別變數, 當按下登入鈕時呼叫類別變數的 get() 方法取得輸入值, 經比對帳密都是 admin 就以 messagebox 訊息盒顯示登入成功. 按下清除鈕則呼叫類別變數的 set() 方法將其內容清空, 結果如下 :
一般來說, 密碼欄位通常會用 * 字元顯示, 這可以透過 show 參數來設定. 另外如登入按鈕所示 grid 版面管理員預設是置中對齊, 這可以用 sticky 參數設為 tk.E, tk.W, tk.S, 或 tk.N 來對齊 (也可以用 + 來複合), 例如 :
測試 4 : tk 模擬登入頁面 (使用 show 密碼參數) [看原始碼]
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox as msgbox
def clear():
account.set("")
pwd.set("")
def login():
if account.get() == "admin" and pwd.get() == "admin":
msgbox.showinfo("Info", "登入成功")
else:
msgbox.showinfo("Info", "帳號或密碼錯誤")
win=tk.Tk()
win.title("tkinter GUI 測試")
win.geometry("300x150")
account=tk.StringVar()
pwd=tk.StringVar()
tk.Label(win, width=5, text="帳號").grid(row=0, column=0)
tk.Entry(win, textvariable=account).grid(row=0, column=1)
tk.Label(win, width=5, text="密碼").grid(row=1, column=0)
tk.Entry(win, show="*", textvariable=pwd).grid(row=1, column=1)
tk.Button(text="清除", command=clear).grid(row=2, column=0, sticky=tk.W)
tk.Button(text="登入", command=login).grid(row=2, column=1, sticky=tk.W)
win.mainloop()
此例將 Label 的寬度設為 5 個字元較能看出按鈕的 sticky 效果, 結果如下 :
下面是上面範例的 ttk 版本 :
測試 5 : ttk 模擬登入頁面 [看原始碼]
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox as msgbox
def clear():
account.set("")
pwd.set("")
def login():
if account.get() == "admin" and pwd.get() == "admin":
msgbox.showinfo("Info", "登入成功")
else:
msgbox.showinfo("Info", "帳號或密碼錯誤")
win=tk.Tk()
win.title("tkinter GUI 測試")
win.geometry("350x150")
account=tk.StringVar()
pwd=tk.StringVar()
ttk.Label(win, text="帳號").grid(row=0, column=0)
ttk.Entry(win, textvariable=account).grid(row=0, column=1)
ttk.Label(win, text="密碼").grid(row=1, column=0)
ttk.Entry(win, show="*", textvariable=pwd).grid(row=1, column=1)
ttk.Button(text="清除", command=clear).grid(row=2, column=0, sticky=tk.W)
ttk.Button(text="登入", command=login).grid(row=2, column=1, sticky=tk.W)
win.mainloop()
由於 ttk 按鈕預設寬度較大, 故視窗寬度放寬為 350px, 結果如下 :
下面這個範例是做華氏與攝式溫度互轉 :
測試 6 : 華氏與攝氏溫度互轉 [看原始碼]
import tkinter as tk
from tkinter import ttk
def f2c():
c.set((f.get() - 32) * 5/9)
def c2f():
f.set(c.get() * 9/5 + 32)
win=tk.Tk()
win.title("tkinter GUI 測試")
win.geometry("500x150")
f=tk.DoubleVar()
c=tk.DoubleVar()
tk.Label(win, text="華氏溫度").grid(row=0, column=0)
tk.Label(win, text="攝氏溫度").grid(row=0, column=2)
tk.Entry(win, textvariable=f).grid(row=1, rowspan=2, column=0)
tk.Button(win, text="=>", command=f2c).grid(row=1, column=1)
tk.Entry(win, textvariable=c).grid(row=1, rowspan=2, column=2)
tk.Button(win, text="<=", command=c2f).grid(row=2, column=1)
win.mainloop()
此例使用兩個 Entry 元件來輸入華氏與攝氏溫度, 他們用 textvariable 參數分別與兩個 DoubleVar 類別變數綁定, 以便能在程式中動態更改其內容. 另外還有兩個用 command 參數指定事件處理函式的方向按鈕用來互轉溫度, 結果如下 :
下面是計算 BMI 的範例 :
測試 7 : 計算 BMI (身高體重指數) [看原始碼]
import tkinter as tk
from tkinter import ttk
def calculate_bmi():
h=float(height.get()) / 100
w=float(weight.get())
bmi=w / h ** 2
if bmi < 18.5:
comment="體重過輕"
elif bmi >= 18.5 and bmi < 24:
comment="體重適當"
else:
comment="體重過重"
msg=f"BMI 指數={bmi:.2f}, {comment}"
result.set(msg)
win=tk.Tk()
win.title("tkinter GUI 測試")
win.geometry("350x150")
height=tk.DoubleVar()
weight=tk.DoubleVar()
result=tk.StringVar()
tk.Label(win, text="身高 (公分)").grid(row=0, column=0)
tk.Label(win, text="體重 (公斤)").grid(row=1, column=0)
tk.Entry(win, textvariable=height).grid(row=0, column=1)
tk.Entry(win, textvariable=weight).grid(row=1, column=1)
tk.Button(text="計算 BMI", command=calculate_bmi).grid(row=2, column=1)
tk.Label(win, textvariable=result).grid(row=3, columnspan=2, column=0)
win.mainloop()
此例使用兩個 Entry 元件取得使用者輸入的身高與體重, 分別綁定到 height 與 weight 這兩個 DoubleVar 變數類別物件, 當按下按鈕時呼叫 calculate_bmi() 來計算 BMI 數值並判斷體重是否過重, 最後將結果透過綁定到 Label 元件的 StringVar 變數類別物件動態更新 Label 的內容 :
參考 :
可以在Entry上面顯示預設的字串
回覆刪除result=tk.StringVar(win, value="default text")
thank you!
回覆刪除