不間斷 Python 挑戰 Day 30 - 使用tkinter開發GUI程式:常用視窗元件

2022/04/13閱讀時間約 19 分鐘
之前的文章中介紹過了Turtle Graphics,它是架構於tkinter模組之上以實現基本圖形介面的繪圖模組,這篇文章就來說明tkinter模組常用元件(widget)的基本用法,以及如何用它來設計出一個具有圖形使用者介面(Graphical User Interface, GUI)的程式。tkinter是Python內建的模組,使用時將它import進來即可,不需額外安裝,詳細用法可以參照以下官方文件:
https://docs.python.org/3/library/tkinter.html
https://www.tcl.tk/man/tcl8.6/TkCmd/contents.html

視窗(Window)

首先,將tkinter模組載入後,先以Tk()方法建立一個根視窗(root window)以放置其它的元件,與視窗相關的常用方法如下:
title():設定視窗標題
geometry("widthxheight"):設定視窗的寬與高,單位是像素(pixel)
minsize(width=int, height=int):設定視窗最小的寬與高,單位是像素(pixel)
maxsize(width=int, height=int):設定視窗最大的寬與高,單位是像素(pixel)
resizable(width=bool, height=bool):設定是否可更改視窗寬與高的大小
mainloop():等待處理視窗事件,讓程式可以繼續執行
from tkinter import *
window = Tk()
window.title("Hello World!")
window.minsize(width=500, height=500)
window.resizable(width=False, height=False)
window.mainloop()
執行結果:
根視窗

元件(Widget)

標籤(Label)

Label()方法可建立文字或圖形標籤,Label()的第一個參數為要包含這個標籤的視窗物件,也可省略不寫,其它常用的參數如下:
text:設定文字內容
font:設定字型與大小
width:設定寬度,單位是字元
height:設定高度,單位是字元
padx:設定左右空白的空間,單位是像素
pady:設定上下空白的空間,單位是像素
background/bg:設定背景顏色
foreground/fg:設定文字顏色
為了讓標籤出現在視窗,可以使用pack()方法將標籤包裝到視窗上,此方法也適用在其它元件上,詳細視窗元件配置的方法之後會在提到。
label = Label(text="my label", font=("Arial", 14, "bold"), padx=5, pady=5, bg="red", fg="yellow")
label.pack()
執行結果:
標籤

按鈕(Button)

按鈕可讓使用者在按下後執行某一些行為,因此除了按鈕本身的設定以外,還需要定義按下按鈕時所要執行的事件處理函式。Button()方法可建立按鈕元件,Button()的第一個參數為要包含這個按鈕的視窗物件,也可省略不寫,其它常用的參數如下:
text:設定按鈕文字
font:設定字型與大小
width:設定寬度,單位是字元
height:設定高度,單位是字元
padx:設定左右空白的空間,單位是像素
pady:設定上下空白的空間,單位是像素
background/bg:設定背景顏色
foreground/fg:設定文字顏色
command:按鈕按下後所要執行的方法
以下範例定義一個button_clicked()方法,當按下按鈕後,透過config()方法修改標籤的text參數,印出"Hello World!"。
def button_clicked():
  label.config(text="Hello World!")

button = Button(text="Click Me", font=("Arial", 14, "bold"), padx=5, pady=5, bg="blue", fg="light green", command=button_clicked)
button.pack()
執行結果:
按鈕

文字方塊(Entry)

文字方塊為單行的文字輸入區域,由Entry()方法來建立物件,Entry()的第一個參數為要包含這個文字方塊的視窗物件,也可省略不寫,其它常用的參數如下:
font:設定字型與大小
width:設定寬度,單位是字元
padx:文字最左或最右與文字方塊邊框的間距,單位是像素
pady:文字最上或最下與文字方塊邊框的間距,單位是像素
background/bg:設定背景顏色
foreground/fg:設定文字顏色
state:設定是否可輸入文字,預設為NORMAL,表示可以輸入,若設定為DISABLED則無法輸入
show:輸入文字時顯示的字元,例如用在輸入密碼時可設定show="*"以顯示星號
此外,還有一些常用的方法:
insert(index, string):在第index個字元前插入字串string
get():取得文字方塊內的文字
以下的範例在文字方塊中寫入"some text",END表示從文字的最末端開始插入,並在PyCharm的輸出視窗中印出文字方塊中的文字。
entry = Entry(width=30, font=("Arial", 14, "bold"), bg="red", fg="yellow", state=NORMAL)
entry.insert(END, string="some text")
entry.pack()
print(entry.get())
執行結果:
文字方塊
some text

文字區域(Text)

文字區域和文字方塊類似,差別在於文字區域可以輸入多行的文字,由Text()方法來建立物件,Text()的第一個參數為要包含這個文字區域的視窗物件,也可省略不寫,其它常用的參數如下:
font:設定字型與大小
width:設定寬度,單位是字元
height:設定高度,單位是字元
background/bg:設定背景顏色
foreground/fg:設定文字顏色
state:設定是否可輸入文字,預設為NORMAL,表示可以輸入,若設定為DISABLED則無法輸入
和文字方塊類似,有一些常用的方法:
insert(index, string):在第index個字元前插入字串string
get("row1.index1", "row2.index2"):取得從row1行第index1之後到row2行第index2個字元的文字
以下範例在文字區域中寫入三行文字,分別是"line 1"、"line 2"、以及"line 3",並在PyCharm的輸出視窗中印出從第一行開始到第二行的第四個字元。
text = Text(height=5, width=30, font=("Arial", 14, "bold"), bg="blue", fg="light green", state=NORMAL)=
text.insert(END, "line 1\nline 2\nline 3")
text.pack()
print(text.get("1.0", "2.4"))
執行結果:
文字區域
line 1
line

Spinbox

Spinbox可以輸入文字,並可以用捲軸來調整文字內容,由Spinbox()方法來建立物件,第一個參數為要包含這個Spinbox的視窗物件,也可省略不寫,其它常用的參數如下:
from_:當內容為數字時的初值
to:當內容為數字時的終值
font:設定字型與大小
width:設定寬度,單位是字元
background/bg:設定背景顏色
foreground/fg:設定文字顏色
state:設定是否可更改內容,預設為NORMAL,表示可以更動,若設定為DISABLED則無法輸入或使用
command:按下捲軸按鈕後所要執行的方法
以下範例建立一個可調整數字區間為0到10的Spinbox,當按下捲軸按鈕時,使用get()方法取得Spinbox的文字內容並輸出。
def spinbox_used():
  print(spinbox.get())

spinbox = Spinbox(from_=0, to=10, width=5, font=("Arial", 14, "bold"), command=spinbox_used, bg="red", fg="yellow", state=NORMAL)
spinbox.pack()
執行結果:
Spinbox
1
2
3
4
5
6
7
8
9
10

Scale

Scale帶有一個可移動的滑桿,用來調整一固定連續範圍內的數字,由Scale()方法建立物件,第一個參數為要包含這個Scale的視窗物件,也可省略不寫,其它常用的參數如下:
from_:連續數字範圍的初值
to:連續數字範圍的終值
font:設定字型與大小
width:設定滑桿寬度,單位是像素
background/bg:設定背景顏色
foreground/fg:設定文字顏色
orient:設定滑桿為水平(HORIZONTAL)或垂直(VERTICAL),預設為垂直
length:設定滑桿長度,預設為100像素
以下範例建立一個可調整數字區間為0到10的水平Scale,當滑動滑桿時,會將目前調整的數值傳入command指定的函數中並輸出。
def scale_used(value):
  print(value)

scale = Scale(from_=0, to=10, font=("Arial", 14, "bold"), width=15, orient=HORIZONTAL, length=200, command=scale_used)
scale.pack()
執行結果:
Scale
1
2
3
4
5
6
7
8
9
10

選項鈕(Radiobutton)

選項鈕可讓使用者點擊勾選,並且同時只有一個選項鈕可以被選取,由Radiobutton()方法建立物件,第一個參數為要包含這個選項鈕的視窗物件,也可省略不寫,其它常用的參數如下:
text:設定選項鈕旁的文字
font:設定字型與大小
width:設定文字的寬度,單位是字元
height:設定文字的行數
padx:設定左右空白的空間,單位是像素
pady:設定上下空白的空間,單位是像素
background/bg:設定背景顏色
foreground/fg:設定文字顏色
value:選項鈕的值
command:點擊選項鈕時所要執行的方法
variable:設定或取得目前選取的選項按鈕
以下範例建立兩個選項鈕,並使用tkinter的整數類別變數radio_state來存取目前選取的選項鈕,當選項鈕被選取時,在輸出視窗中印出目前選取的按鈕。
def radiobutton_used():
  print(radio_state.get())

radio_state = IntVar()
radiobutton1 = Radiobutton(text="Option1", value=1, variable=radio_state, command=radiobutton_used)
radiobutton2 = Radiobutton(text="Option2", value=2, variable=radio_state, command=radiobutton_used)
radiobutton1.pack()
radiobutton2.pack()
執行結果:
選項鈕
1
2
1

核取方塊(Checkbutton)

相較於選項鈕只能單選,核取方塊可以一次選取多個項目,由Checkbutton()方法建立物件,第一個參數為要包含這個核取方塊的視窗物件,也可省略不寫,其它常用的參數如下:
text:設定核取方塊旁的文字
font:設定字型與大小
width:設定文字的寬度,單位是字元
height:設定文字的行數
padx:設定左右空白的空間,單位是像素
pady:設定上下空白的空間,單位是像素
background/bg:設定背景顏色
foreground/fg:設定文字顏色
command:點擊核取方塊時所要執行的方法
variable:設定或取得目前選取的核取方塊
以下範例建立兩個核取方塊,並使用兩個tkinter的整數變數來存取目前選取的核取方塊,當核取方塊被選取時,在輸出視窗中印出目前選取的選項。
def checkbutton_clicked():
  print(f"Option1: {checked_state1.get()}, Option2: {checked_state2.get()}")

checked_state1 = IntVar()
checked_state2 = IntVar()

checkbutton1 = Checkbutton(text="Option1", variable=checked_state1, command=checkbutton_clicked)
checkbutton2 = Checkbutton(text="Option2", variable=checked_state2, command=checkbutton_clicked)
checkbutton1.pack()
checkbutton2.pack()
執行結果:
核取方塊
Option1: 1, Option2: 0
Option1: 1, Option2: 1
Option1: 0, Option2: 1

列表選單

列表選單可在表單內顯示多個選項,使用者可做單選或多選,由Listbox()方法來建立物件,第一個參數為要包含這個列表選單的視窗物件,也可省略不寫,其它常用的參數如下:
font:設定字型與大小
width:設定文字的寬度,單位是字元
height:設定文字的行數
background/bg:設定背景顏色
foreground/fg:設定文字顏色
selectmode:設定選項為單選或多選,以及滑鼠拖曳時的選取方式
  BROWSE:單選,點擊後拖曳滑鼠最後放開的位置為選取項目,此為預設
  SINGLE:單選,點擊項目即為選取項目,不受滑鼠拖曳影響
  MULTIPLE:多選,點擊項目即為選取項目,再點一下可取消選取
  EXTENDED:多選,點擊後拖曳滑鼠到最後放開的區間為選取項目,或點選
         第一個項目後,按下shift點選第二個項目,兩者的區間即為選
         取項目
以下範例建立一個包含四個選項的列表選單,並設定選取方式為可拖曳多選。
listbox = Listbox(width=15, height=4, selectmode=EXTENDED)
options = ["Option1", "Option2", "Option3", "Option4"]
for item in options:
  listbox.insert(options.index(item), item)
listbox.pack()
列表選單

功能表(Menu)

功能表一般位於視窗的最上層,屬於一種下拉式的表單,由Menu()方法來建立物件,第一個參數為要包含這個列表選單的視窗物件,也可省略不寫,其它常用的參數如下:
font:設定功能表項目的字型與大小
activebackground:設定功能表項目被選取時的背景顏色
activeforeground:設定功能表項目被選取時的文字顏色
activeborderwidth:設定功能表項目被選取時的背景寬度
borderwidth:設定功能表項目的表單寬度
background/bg:設定功能表項目未被選取時的背景顏色
foreground/fg:設定功能表項目未被選取時的文字顏色
image:設定功能表項目的圖示
tearoff:設定功能表上方的虛線分隔線,預設有分隔線,tearoff為1,此時按一下分隔線可將功能表分離;tearoff設為0則無分隔線
搭配常用的方法如下:
add_cascade():建立階層式的功能表
add_command():增加功能表的項目
add_separator():增加功能表項目間的分隔線
以下範例程式建立一個含有兩個子功能表的功能表選單,在第一個子功能表menu1中,增加兩個功能表項目,項目之間有分隔線,並且可按功能表上方的虛線將功能表分離。
menu = Menu()
window.config(menu=menu)

submenu1 = Menu(activebackground="green", activeborderwidth=10, borderwidth=20)
menu.add_cascade(label="menu1", menu=submenu1)

submenu1.add_command(label="label1")
submenu1.add_separator()
submenu1.add_command(label="label2")

submenu2 = Menu()
menu.add_cascade(label="menu2", menu=submenu2)
執行結果:
功能表
功能表分離

總結

這篇文章中列出了一些使用tkinter建立GUI程式時常見的視窗元件,以及基本的參數用法,很多沒有提到的參數,使用時都可以到開頭提到的網站上查詢,全部寫出來就顯得冗長了。然而可以注意到,到目前為止所建立的元件都是由上而下依序排列下來,實際設計界面時,我們還要考量到元件所擺放的位置,這就留到下篇文章中再來說明。

程式範例

為什麼會看到廣告
Wei-Jie Weng
Wei-Jie Weng
留言0
查看全部
發表第一個留言支持創作者!