- 原文博客地址: Tkinter之組件布局和事件綁定
-
前面的一些文章介紹了
Tkinter
模塊和大部分組建的使用 - 這里主要介紹數(shù)據(jù)的操作和組件布局等
- GitHub代碼示例目地址
一. 數(shù)據(jù)顯示
在tkinter
中的數(shù)據(jù)展示方式有兩種表格數(shù)據(jù)和樹狀數(shù)據(jù), 但是都用到同一個組件Treeview
, 下面介紹組建的使用
1. 表格數(shù)據(jù)
- 表格數(shù)據(jù), 顧名思義就是用表格形式展示數(shù)據(jù)
- 要使用
Treeview
首先要引用tkinter
中的ttk
模塊
from tkinter import ttk
# 此處省略window的相關(guān)代碼
# 創(chuàng)建表格
tree = ttk.Treeview(window)
tree.pack()
# 定義列title(接受一個元組)
tree["columns"] = ('name', 'sex', 'age', 'height', 'weight')
# 設(shè)置列寬度
tree.column('name', width=100)
tree.column('sex', width=50)
tree.column('age', width=50)
tree.column('height', width=80)
tree.column('weight', width=80)
# 設(shè)置表頭(列名)
tree.heading('name', text='姓名')
tree.heading('sex', text='性別')
tree.heading('age', text='年齡')
tree.heading('height', text='身高(CM)')
tree.heading('weight', text='體重(KG)')
# 添加數(shù)據(jù)
tree.insert('', 0, text='line1', values=('Titan', 'M', 20, 180, 80))
tree.insert('', 1, text='line2', values=('Jun', 'M', 19, 170, 65))
tree.insert('', 2, text='line3', values=('Coder', 'M', 20, 170, 70))
tree.insert('', 3, text='line4', values=('Che', 'W', 18, 165, 45))
# 上面第一個參數(shù)為第一層級, 這里目前用不到, 后面樹狀結(jié)構(gòu)中會用到
效果圖如下
2. 樹狀數(shù)據(jù)
樹狀數(shù)據(jù)這里指的是,類似文件夾的層級目錄一樣
# 創(chuàng)建表格
tree = ttk.Treeview(window)
tree.pack()
# 添加一級樹枝
treeA1 = tree.insert('', 0, '浙', text='浙江', values=('A1'))
treeA2 = tree.insert('', 1, '魯', text='山東', values=('A2'))
treeA3 = tree.insert('', 2, '蘇', text='江蘇', values=('A3'))
# 添加二級樹枝
treeA1_1 = tree.insert(treeA1, 0, 'H', text='杭州', values=('A1_1'))
treeA1_2 = tree.insert(treeA1, 1, 'Z', text='舟山', values=('A1_2'))
treeA1_3 = tree.insert(treeA1, 2, 'J', text='嘉興', values=('A1_3'))
treeA2_1 = tree.insert(treeA2, 0, 'N', text='濟(jì)南', values=('A2_1'))
treeA2_2 = tree.insert(treeA2, 1, 'L', text='臨沂', values=('A2_2'))
treeA2_3 = tree.insert(treeA2, 2, 'Q', text='青島', values=('A2_3'))
treeA2_4 = tree.insert(treeA2, 3, 'Y', text='煙臺', values=('A2_4'))
# 三級樹枝
treeA1_1_1 = tree.insert(treeA1_1, 0, 'G', text='江干', values=('A1_1_1'))
treeA1_1_1 = tree.insert(treeA1_1, 1, 'X', text='蕭山', values=('A1_1_2'))
注意事項
-
insert
: 參數(shù)介紹- 參數(shù)1: 上一層級的目錄
- 參數(shù)2: 當(dāng)前數(shù)據(jù)在當(dāng)前層級的中的索引值
- 參數(shù)3: 當(dāng)前數(shù)據(jù)的標(biāo)識, 所有層及數(shù)據(jù)的該標(biāo)識不能相同, 否則報錯
- 參數(shù)4: 顯示的數(shù)據(jù)
- 注: 所有數(shù)據(jù)的參數(shù)3(標(biāo)識)不能相同
效果圖如下
二. 布局方式
- 所謂布局场梆,就是指控制窗體容器中各個控件(組件)的位置關(guān)系。
- 在
tkinter
中目前存在的布局方式有三種: 絕對布局(place
), 相對布局(pack
)和表格布局(grid
)
1. 絕對布局
- 絕對布局: 窗口的變化對位置沒有影響
- 這里先介紹
place
布局涉及到的相關(guān)屬性和函數(shù)
1-1. 屬性介紹
屬性名 | 屬性簡析 | 取值 | 取值說明 |
---|---|---|---|
anchor |
錨點, 當(dāng)可用空間大于所需求的尺寸時,決定組件被放置于容器的何處 | N、E、S娇昙、W、NW、NE杯拐、SW、SE世蔗、CENTER (默認(rèn)值) |
表示八個方向以及中心 |
x端逼、y |
組件左上角的x、y坐標(biāo) | 整數(shù)污淋,默認(rèn)值0 | 絕對位置坐標(biāo)顶滩,單位像素 |
relx/rely |
組件相對于父容器的x、y坐標(biāo) | 0~1之間浮點數(shù) | 相對位置寸爆,0.0表示左邊緣(或上邊緣)礁鲁,1.0表示右邊緣(或下邊緣) |
width/height |
組件的寬度、高度 | 非負(fù)整數(shù) | 單位像素 |
relwidth赁豆、relheight |
組件相對于父容器的寬度仅醇、高度 | 0~1之間浮點數(shù) | 與relx(rely) 取值相似 |
bordermode |
如果設(shè)置為INSIDE ,組件內(nèi)部的大小和位置是相對的魔种,不包括邊框析二;如果是OUTSIDE ,組件的外部大小是相對的节预,包括邊框 |
INSIDE (默認(rèn))叶摄、OUTSIDE
|
可以使用常量INSIDE 漆改、OUTSIDE ,也可以使用字符串形式inside 准谚、outside
|
# 創(chuàng)建四個label
label1 = Label(window, text='11111', bg='red')
label2 = Label(window, text='22222', bg='yellow')
label3 = Label(window, text='33333', bg='blue')
label4 = Label(window, text='44444', bg='orange')
# 絕對布局
label1.place(x=10, y=10, width=200)
label2.place(x=30, y=30)
label3.place(x=60, y=61)
label4.place(x=91, y=91, width=200, height=50)
如下圖組件位置固定
1-2. 相關(guān)函數(shù)
place
類提供了下列函數(shù)(使用組件實例對象調(diào)用)
-
place_slaves()
: 以列表方式返回本組件的所有子組件對象 -
place_configure(option=value)
: 給place
布局管理器設(shè)置屬性挫剑,使用屬性option=value
方式設(shè)置 -
propagate(boolean)
: 設(shè)置為True
表示父組件的幾何大小由子組件決定(默認(rèn)值),反之則無關(guān) -
place_info()
: 返回place
提供的選項所對應(yīng)得值 -
grid_forget()
:Unpack
組件柱衔,將組件隱藏并且忽略原有設(shè)置樊破,對象依舊存在,可以用pack(option, …)
唆铐,將其顯示 -
location(x, y)
:x/y
為以像素為單位的點哲戚,函數(shù)返回此點是否在單元格中,在哪個單元格中艾岂。返回單元格行列坐標(biāo)顺少,(-1, -1)表示不在其中 -
size()
: 返回組件所包含的單元格,揭示組件大小
2. 相對布局
2-1. 屬性介紹
- 相對布局: 組件位置或大小的變化會隨著窗口的變化而變化
- 這里先介紹
pack
布局涉及到的相關(guān)屬性和函數(shù)
屬性名 | 屬性簡析 | 取值 | 取值說明 |
---|---|---|---|
fill |
設(shè)置組件是否向水平或垂直方向填充 | X王浴、Y脆炎、BOTH和NONE |
fill=X (水平方向填充),BOTH (水平和垂直),NONE 不填充 |
expand |
設(shè)置組件是否展開 | YES、NO(1氓辣、0) | expand=YES |
side |
設(shè)置組件的對齊方式 | LEFT秒裕、TOP、RIGHT钞啸、BOTTOM |
值為左几蜻、上、右体斩、下 |
ipadx/ipady |
設(shè)置x方向(或者y方向)內(nèi)部間隙(子組件之間的間隔) | 可設(shè)置數(shù)值梭稚,默認(rèn)是0 | 非負(fù)整數(shù),單位為像素 |
padx/pady |
設(shè)置x方向(或者y方向)外部間隙(與之并列的組件之間的間隔) | 可設(shè)置數(shù)值絮吵,默認(rèn)是0 | 非負(fù)整數(shù)弧烤,單位為像素 |
anchor |
錨選項,當(dāng)可用空間大于所需求的尺寸時源武,決定組件被放置于容器的何處 | N扼褪、E、S粱栖、W、NW脏毯、NE闹究、SW、SE食店、CENTER(默認(rèn)值為CENTER) | 表示八個方向以及中心 |
需要注意
expand
: 設(shè)置組件是否展開渣淤,當(dāng)值為YES時赏寇,side
選項無效。組件顯示在父容器中心位置价认;若fill
選項為BOTH
,則填充父組件的剩余空間嗅定。默認(rèn)為不展開
# 創(chuàng)建四個label
label1 = Label(window, text='11111', bg='red')
label2 = Label(window, text='22222', bg='yellow')
label3 = Label(window, text='33333', bg='blue')
label4 = Label(window, text='44444', bg='orange')
# 布局
label1.pack(side=LEFT, fill=Y)
label2.pack(side=RIGHT, fill=Y)
label3.pack(side=TOP, fill=X)
label4.pack(side=BOTTOM, fill=X)
效果如圖
2-2. 函數(shù)介紹
pack
類提供了下列函數(shù)(使用組件實例對象調(diào)用)
-
pack_slaves()
: 以列表方式返回本組件的所有子組件對象 -
pack_configure(option=value)
: 給pack
布局管理器設(shè)置屬性,使用屬性option=value
方式設(shè)置 -
propagate(boolean)
: 設(shè)置為 True 表示父組件的幾何大小由子組件決定(默認(rèn)值)用踩,反之則無關(guān)渠退。 -
ack_info()
: 返回pack提供的選項所對應(yīng)得值。 -
pack_forget()
:Unpack
組件脐彩,將組件隱藏并且忽略原有設(shè)置碎乃,對象依舊存在,可以用pack(option, …)
惠奸,將其顯示梅誓。 -
location(x, y)
: x, y為以像素為單位的點,函數(shù)返回此點是否在單元格中佛南,在哪個單元格中梗掰。返回單元格行列坐標(biāo),(-1, -1)表示不在其中 -
size()
: 返回組件所包含的單元格嗅回,揭示組件大小
3. 表格布局
-
grid
布局又被稱作網(wǎng)格布局愧怜,是最被推薦使用的布局。 - 程序大多數(shù)都是矩形的界面妈拌,我們可以很容易把它劃分為一個幾行幾列的網(wǎng)格拥坛,然后根據(jù)行號和列號,將組件放置于網(wǎng)格之中
- 使用
grid
布局時尘分,需要在里面指定兩個參數(shù)猜惋,分別用row
表示行,column
表示列 - 需要注意的是
row
和column
的序號都從0開始
3-1. 屬性介紹
屬性名 | 屬性簡析 | 取值 | 取值說明 |
---|---|---|---|
row/column |
row 為行號培愁,column 為列號著摔,設(shè)置將組件放置于第幾行第幾列 |
取值為行、列的序號定续,不是行數(shù)與列數(shù) |
row 和column 的序號都從0 開始 |
sticky |
設(shè)置組件在網(wǎng)格中的對齊方式 | N谍咆、E、S私股、W摹察、NW、NE倡鲸、SW供嚎、SE、CENTER |
類似于pack 布局中的錨選項 |
rowspan |
組件所跨越的行數(shù) | 跨越的行數(shù) | 取值為跨越占用的行數(shù),而不是序號 |
columnspan |
組件所跨越的列數(shù) | 跨越的列數(shù) | 取值為跨越占用的列數(shù)克滴,而不是序號 |
ipadx/ipady |
設(shè)置x方向(或者y方向)內(nèi)部間隙(子組件之間的間隔) | 可設(shè)置數(shù)值逼争,默認(rèn)是0 | 非負(fù)整數(shù),單位為像素 |
padx/pady |
設(shè)置x方向(或者y方向)外部間隙(與之并列的組件之間的間隔) | 可設(shè)置數(shù)值劝赔,默認(rèn)是0 | 非負(fù)整數(shù)誓焦,單位為像素 |
# 創(chuàng)建四個label
label1 = Label(window, text='11111', bg='red')
label2 = Label(window, text='22222', bg='yellow')
label3 = Label(window, text='33333', bg='blue')
label4 = Label(window, text='44444', bg='orange')
# 布局
label1.grid(row=0, column=0)
label2.grid(row=0, column=1)
label3.grid(row=1, column=0)
label4.grid(row=1, column=1)
效果如圖
3-2. 函數(shù)介紹
grid
類提供了下列函數(shù)(使用組件實例對象調(diào)用):
函數(shù)名 | 描述 |
---|---|
grid_slaves() |
以列表方式返回本組件的所有子組件對象。 |
grid_configure(option=value) |
給grid 布局管理器設(shè)置屬性 |
grid_propagate(boolean) |
設(shè)置為True 表示父組件的幾何大小由子組件決定(默認(rèn)值)着帽,反之則無關(guān)杂伟。 |
grid_info() |
返回grid 提供的選項所對應(yīng)得值。 |
grid_forget() |
將組件隱藏并且忽略原有設(shè)置启摄,對象依舊存在 |
grid_location(x, y) |
x/y 為以像素為單位的點稿壁,函數(shù)返回此點是否在單元格中 |
size() |
返回組件所包含的單元格,揭示組件大小 |
三. 鼠標(biāo)和鍵盤事件
- 一個
Tkinter
應(yīng)用生命周期中的大部分時間都處在一個消息循環(huán)中 - 它等待事件的發(fā)生: 事件可能是按鍵按下, 鼠標(biāo)點擊, 鼠標(biāo)移動等.
-
Tkinter
提供了用以處理相關(guān)事件的機(jī)制, 處理函數(shù)可以被綁定給各個控件的各種事件 - 如果相關(guān)事件發(fā)生,
handler
函數(shù)會被觸發(fā), 事件對象event
會傳遞給handler
函數(shù)
button.bind(event, handler)
1. 鼠標(biāo)點擊事件
def buttonAction(event):
print(event.x, event.y)
button = Button(window, text='這是一個按鈕')
button.bind('<Button-4>', buttonAction)
button.pack()
其中event
的事件類型和描述如下
Event | Description |
---|---|
<Button-1> |
鼠標(biāo)左鍵 |
<Button-3> |
鼠標(biāo)右鍵 |
<Button-2> |
鼠標(biāo)中鍵 |
<Button-4> |
鼠標(biāo)向上滾動 |
<Button-5> |
鼠標(biāo)向下滾動 |
<Double-Button-1> |
鼠標(biāo)左鍵雙擊 |
<Double-Button-3> |
鼠標(biāo)右鍵雙擊 |
<Double-Button-2> |
鼠標(biāo)中鍵雙擊 |
<Triple-Button-1> |
鼠標(biāo)左鍵三擊 |
<Triple-Button-3> |
鼠標(biāo)右鍵三擊 |
<Triple-Button-2> |
鼠標(biāo)中鍵三擊 |
2. 鼠標(biāo)在某個按鍵被按下后的移動事件
label = Label(window, text='https://www.titanjun.top', bg='orange')
label.place(x=100, y=50, height=30)
def labelAction(event):
print(event.x, event.y)
label.bind('<B1-Motion>', labelAction)
其中event
的事件類型和描述如下
Event | Description |
---|---|
<B1-Motion> |
左鍵移動 |
<B3-Motion> |
右鍵移動 |
<B2-Motion> |
中鍵移動 |
3. 按鈕點擊釋放事件
label = Label(window, text='https://www.titanjun.top', bg='orange')
label.place(x=100, y=50, height=30)
def labelAction(event):
print(event.x, event.y)
label.bind('<ButtonRelease-1>', labelAction)
其中event
的事件類型和描述如下
Event | Description |
---|---|
<ButtonRelease-1> |
釋放鼠標(biāo)左鍵 |
<ButtonRelease-3> |
釋放鼠標(biāo)右鍵 |
<ButtonRelease-2> |
釋放鼠標(biāo)中鍵 |
需要注意的是
- 以上鼠標(biāo)操作中, 蘋果鼠標(biāo)沒有中鍵這一說, 所以在蘋果鼠標(biāo)操作中
- 正常鼠標(biāo)的中鍵操作(例如
<Button-2>
等-2
操作), 響應(yīng)蘋果鼠標(biāo)的右鍵操作 - 正常鼠標(biāo)的右鍵操作(例如
<Button-3>
等-3
操作), 在蘋果鼠標(biāo)中無響應(yīng)
4. 鼠標(biāo)進(jìn)入/離開控件事件
# 按鈕點擊釋放事件
label3 = Label(window, text='加油: https://www.titanjun.top', bg='yellow')
label3.place(x=100, y=150, height=30)
def labelAction(event):
print(event.x, event.y)
label3.bind('<Leave>', labelAction)
其中event
的事件類型和描述如下
Event | Description |
---|---|
<Enter> |
鼠標(biāo)光標(biāo)進(jìn)入控件時觸發(fā) |
<Leave> |
鼠標(biāo)光標(biāo)離開控件時觸發(fā) |
5. 鍵盤響應(yīng)事件
# 響應(yīng)所有的按鍵
label = Label(window, text='https://www.titanjun.top', bg='orange')
# 設(shè)置焦點
label.focus_set()
label.place(x=100, y=50, height=30)
def labelAction(event):
print(event.char, event.keycode)
label.bind('<Key>', labelAction)
其他按鍵操作
Event | Description |
---|---|
<Key> |
響應(yīng)所有的按鍵(按下) |
<KeyRelease> |
響應(yīng)所有的按鍵(松開) |
<FocusIn> |
控件或控件的子空間獲得鍵盤焦點. |
<FocusOut> |
控件丟失鍵盤焦點 (焦點移動到另一個控件). |
6. 指定按鍵操作
Event | Description |
---|---|
<Return>/<Enter> |
只有回車鍵響應(yīng) |
<Escape> |
esc鍵 |
<space> |
空格鍵 |
<Tab> |
Tab鍵 |
<Up>/<Down>/<Left>/<Right> |
上下左右鍵 |
<Shitf_L>/<Shift_R> |
左右Shift 鍵(類似有左右兩個鍵的, 添加_L/_R 區(qū)分) |
<BackSpace> |
退格 |
<a>/<b> |
指定的小寫字母鍵 |
<A>/<Z> |
指定的大寫字母鍵 |
<Control-Alt-a> |
組合鍵(可識別任意組合鍵) |
需要注意的是: 識別組合鍵時, 一般是按下組合鍵的最后一個鍵才會觸發(fā)操作
7. event
事件的相應(yīng)參數(shù)
時間屬性 | 描述 |
---|---|
char |
從鍵盤輸入的和按鍵事件的相關(guān)字符 |
keycode |
從按鍵輸入的和按鍵事件的鍵代碼(ASCII碼) |
keysym |
從按鍵輸入的和按鍵事件的鍵符號(即字符) |
num |
按鍵數(shù)字(1, 2, 3)表明按下的是哪個鼠標(biāo)鍵 |
widget |
觸發(fā)這個事件的小構(gòu)件對象 |
x和y |
當(dāng)前鼠標(biāo)在小構(gòu)件中以像素為單位的位置 |
x_root和y_root |
當(dāng)前鼠標(biāo)相對于屏幕左上角的以像素為單位的位置 |