Tkinter之組件布局和事件綁定

Tkinter.png

一. 數(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)中會用到

效果圖如下

Treeview1.png

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)識)不能相同

效果圖如下

Treeview2.png

二. 布局方式

  • 所謂布局场梆,就是指控制窗體容器中各個控件(組件)的位置關(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)

如下圖組件位置固定

place.png

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)

效果如圖

pack.png

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表示列
  • 需要注意的是rowcolumn的序號都從0開始

3-1. 屬性介紹

屬性名 屬性簡析 取值 取值說明
row/column row為行號培愁,column為列號著摔,設(shè)置將組件放置于第幾行第幾列 取值為行、列的序號定续,不是行數(shù)與列數(shù) rowcolumn 的序號都從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)

效果如圖

grid.png

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)相對于屏幕左上角的以像素為單位的位置

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末歉备,一起剝皮案震驚了整個濱河市傅是,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蕾羊,老刑警劉巖喧笔,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異龟再,居然都是意外死亡书闸,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進(jìn)店門利凑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來浆劲,“玉大人,你說我怎么就攤上這事哀澈∨平瑁” “怎么了?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵割按,是天一觀的道長膨报。 經(jīng)常有香客問我,道長适荣,這世上最難降的妖魔是什么现柠? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮弛矛,結(jié)果婚禮上够吩,老公的妹妹穿的比我還像新娘。我一直安慰自己汪诉,他們只是感情好废恋,可當(dāng)我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布谈秫。 她就那樣靜靜地躺著扒寄,像睡著了一般鱼鼓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上该编,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天迄本,我揣著相機(jī)與錄音,去河邊找鬼课竣。 笑死嘉赎,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的于樟。 我是一名探鬼主播公条,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼迂曲!你這毒婦竟也來了靶橱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤路捧,失蹤者是張志新(化名)和其女友劉穎关霸,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體杰扫,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡队寇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了章姓。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片佳遣。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖凡伊,靈堂內(nèi)的尸體忽然破棺而出零渐,到底是詐尸還是另有隱情,我是刑警寧澤窗声,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布相恃,位于F島的核電站,受9級特大地震影響笨觅,放射性物質(zhì)發(fā)生泄漏拦耐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一见剩、第九天 我趴在偏房一處隱蔽的房頂上張望杀糯。 院中可真熱鬧,春花似錦苍苞、人聲如沸固翰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽骂际。三九已至疗琉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間歉铝,已是汗流浹背盈简。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留太示,地道東北人柠贤。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像类缤,于是被迫代替她去往敵國和親臼勉。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內(nèi)容