[譯][Tkinter 教程12] 布局管理 (Pack Place Grid)

原系列地址: Python Tkinter

簡介:

本文講述如何使用 tkinter 的布局管理 (被稱作 layout managers 或 geometry managers). tkinter 有三種布局管理方式:

  • pack
  • grid
  • place

注意這三種布局管理在同一個(gè) master window 里一定不可以混用! 布局管理有以下功能:

  • 將控件放置在屏幕上,包括控件的位置及控件的大小
  • 將控件注冊到本地窗口系統(tǒng)中
  • 管理控件在屏幕上的顯示

雖然控件自己也可以指定大小和對齊方式等信息, 但最終的控件大小及位置還是由布局管理決定的.

Pack 布局管理

pack 是三種布局管理中最常用的. 另外兩種布局需要精確指定控件具體的顯示位置, 而 pack 布局可以指定相對位置, 精確的位置會(huì)由 pack 系統(tǒng)自動(dòng)完成. 這也使得 pack 布局沒有另外兩種布局方式靈活. 所以 pack 是簡單應(yīng)用的首選布局, 比如只是想要將控件水平或垂直的逐個(gè)放在一起:

from Tkinter import *

root = Tk()
Label(root, text="Red Sun", bg="red", fg="white").pack()
Label(root, text="Green Grass", bg="green", fg="black").pack()
Label(root, text="Blue Sky", bg="blue", fg="white").pack()
mainloop()

下面將逐一講解 pack 布局的各個(gè)屬性.

fill 控件填充方式

在上面那個(gè)例子里, 我們簡單的將三個(gè) Label 控件 pack 到其父窗口上, 沒有使用任何屬性. 于是 pack 使用了默認(rèn)方式進(jìn)行布局: 從上到下順次排放, 并水平居中. 同時(shí)我們也發(fā)現(xiàn), pack 默認(rèn)會(huì)將 Label 控件的寬度設(shè)置為其中的文字的寬度. 如果我們想讓它們和其父窗口一樣寬, 可以使用 fill=X 屬性:

from Tkinter import *

root = Tk()
w = Label(root, text="Red Sun", bg="red", fg="white")
w.pack(fill=X)
w = Label(root, text="Green Grass", bg="green", fg="black")
w.pack(fill=X)
w = Label(root, text="Blue Sky", bg="blue", fg="white")
w.pack(fill=X)
mainloop()

padding 控件邊距

Pack 可以在四個(gè)方面控制控件邊距: 內(nèi)邊距, 外邊距, 水平邊距, 垂直邊距:

padx - 設(shè)置水平方向的外邊距

from Tkinter import *

root = Tk()
w = Label(root, text="Red Sun", bg="red", fg="white")
w.pack(fill=X,padx=10)
w = Label(root, text="Green Grass", bg="green", fg="black")
w.pack(fill=X,padx=10)
w = Label(root, text="Blue Sky", bg="blue", fg="white")
w.pack(fill=X,padx=10)
mainloop()

pady - 設(shè)置豎直方向的外邊距

from Tkinter import *

root = Tk()
w = Label(root, text="Red Sun", bg="red", fg="white")
w.pack(fill=X,pady=10)
w = Label(root, text="Green Grass", bg="green", fg="black")
w.pack(fill=X,pady=10)
w = Label(root, text="Blue Sky", bg="blue", fg="white")
w.pack(fill=X,pady=10)
mainloop()

ipadx - 設(shè)置水平方向的內(nèi)邊距

from Tkinter import *

root = Tk()
w = Label(root, text="Red Sun", bg="red", fg="white")
w.pack()
w = Label(root, text="Green Grass", bg="green", fg="black")
w.pack(ipadx=10)
w = Label(root, text="Blue Sky", bg="blue", fg="white")
w.pack()
mainloop()

ipady - 設(shè)置豎直方向的內(nèi)邊距

from Tkinter import *

root = Tk()
w = Label(root, text="Red Sun", bg="red", fg="white")
w.pack()
w = Label(root, text="Green Grass", bg="green", fg="black")
w.pack(ipadx=10)
w = Label(root, text="Blue Sky", bg="blue", fg="white")
w.pack(ipady=10)
mainloop()

上述四個(gè)屬性的默認(rèn)值都是 0.

side 順次放置控件

我們把上面那幾個(gè) Label 從左到右放在一排:

from Tkinter import *

root = Tk()
w = Label(root, text="red", bg="red", fg="white")
w.pack(padx=5, pady=10, side=LEFT)
w = Label(root, text="green", bg="green", fg="black")
w.pack(padx=5, pady=20, side=LEFT)
w = Label(root, text="blue", bg="blue", fg="white")
w.pack(padx=5, pady=20, side=LEFT)
mainloop()

如果把上述 side 屬性的值都改為 RIGHT, 那么上面 Label 控件的排列順序就反過來了:

Place 布局管理

Place 布局管理可以顯式的指定控件的絕對位置或相對于其他控件的位置. 要使用 Place 布局, 調(diào)用相應(yīng)控件的 place() 方法就可以了. 所有 tkinter 的標(biāo)準(zhǔn)控件都可以調(diào)用 place() 方法.

下面是一個(gè)使用 Place 布局的例子: 為 Label 控件設(shè)置隨機(jī)的背景色, 然后計(jì)算各個(gè) Label 的背景色的亮度(灰度值), 如果其亮度小于 120, 則將其前景色(文字顏色, fg 屬性)設(shè)置為白色, 否則設(shè)為黑色. 這樣做是為了避免使背景色和前景色過于接近而導(dǎo)致文字不易閱讀.

import Tkinter as tk
import random

root = tk.Tk()
# width x height + x_offset + y_offset:
root.geometry("170x200+30+30") 

languages = ['Python','Perl','C++','Java','Tcl/Tk']
labels = range(5)
for i in range(5):
   ct = [random.randrange(256) for x in range(3)]
   brightness = int(round(0.299*ct[0] + 0.587*ct[1] + 0.114*ct[2]))
   ct_hex = "%02x%02x%02x" % tuple(ct)
   bg_colour = '#' + "".join(ct_hex)
   l = tk.Label(root, 
                text=languages[i], 
                fg='White' if brightness < 120 else 'Black', 
                bg=bg_colour)
   l.place(x = 20, y = 30 + i*30, width=120, height=25)

root.mainloop()

Grid 布局管理

Pack 作為首選的布局管理方式, 其運(yùn)作方式并不是特別易于理解. 已經(jīng)由 Pack 布局完成的設(shè)計(jì)也很難做出改變. Grid 布局在1996年作為另一種可供選擇的布局方式被引入. Grid 布局方式易學(xué)易用, 但似乎大家還是習(xí)慣用 Pack.

Grid 在很多場景下是最好用的布局方式. 相比而言, Pack 布局在控制細(xì)節(jié)方面有些力不從心. Place 布局雖然可以完全控制控件位置, 但這也導(dǎo)致使用 Place 會(huì)比其他兩種布局方式更加復(fù)雜.

Grid 把控件位置作為一個(gè)二維表結(jié)構(gòu)來維護(hù), 即按照行列的方式排列控件: 控件位置由其所在的行號(hào)和列號(hào)決定. 行號(hào)相同而列號(hào)不同的幾個(gè)控件會(huì)被彼此上下排列; 列號(hào)相同而行號(hào)不同的幾個(gè)控件會(huì)被彼此左右排列.

使用 Grid 布局的過程就是為各個(gè)控件指定行號(hào)和列號(hào)的過程. 不需要為每個(gè)格子指定大小, Grid 布局會(huì)自動(dòng)設(shè)置一個(gè)合適的大小.

下面還是舉個(gè)栗子吧:

from Tkinter import *

colours = ['red','green','orange','white','yellow','blue']

r = 0
for c in colours:
    Label(text=c, relief=RIDGE,width=15).grid(row=r,column=0)
    Entry(bg=c, relief=SUNKEN,width=10).grid(row=r,column=1)
    r = r + 1

mainloop()

譯者水平有限, 如有疏漏, 歡迎指正.
已獲得原作者授權(quán). 原文地址:
Layout Management

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蛇受,老刑警劉巖倘是,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肄方,死亡現(xiàn)場離奇詭異疤剑,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)阳似,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進(jìn)店門骚勘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人撮奏,你說我怎么就攤上這事俏讹。” “怎么了畜吊?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵泽疆,是天一觀的道長。 經(jīng)常有香客問我玲献,道長殉疼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任青自,我火速辦了婚禮株依,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘延窜。我一直安慰自己,他們只是感情好抹锄,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布逆瑞。 她就那樣靜靜地躺著,像睡著了一般伙单。 火紅的嫁衣襯著肌膚如雪获高。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天吻育,我揣著相機(jī)與錄音念秧,去河邊找鬼。 笑死布疼,一個(gè)胖子當(dāng)著我的面吹牛摊趾,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播游两,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼砾层,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了贱案?” 一聲冷哼從身側(cè)響起肛炮,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后侨糟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體碍扔,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年秕重,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了不同。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,932評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡悲幅,死狀恐怖套鹅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情汰具,我是刑警寧澤卓鹿,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站留荔,受9級特大地震影響吟孙,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜聚蝶,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一杰妓、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧碘勉,春花似錦巷挥、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至胜嗓,卻和暖如春高职,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背辞州。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工怔锌, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人变过。 一個(gè)月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓埃元,卻偏偏與公主長得像,于是被迫代替她去往敵國和親牵啦。 傳聞我的和親對象是個(gè)殘疾皇子亚情,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評論 2 354

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