[英]tkinter - understand pack and grid - simple layout. (always confused…)
我正在嘗試配置一個文本框,並在文本框下方連續設置 3 個按鈕,我不想擴展它們以填充所有區域。 只是在中心保持原來的大小。
我試圖用包或網格來做到這一點。 但我真的很困惑。 我還嘗試將文本框和按鈕放在不同的框架上,所以它可能會將小部件分開並讓我配置它而不會弄亂東西(因為一切都是相對於另一個......)......但我什么都沒有這看起來不錯。
我還想學習如何以正確的方式使用網格,如果我有各種小部件和按鈕,一個在另一個下面沒有“列跨度”,或者調整按鈕內的文本長度以匹配它們上面的小部件......
在這個例子中。 我怎樣才能使按鈕居中? 我必須使用 side=tkinter.LEFT 才能將它們一個接一個地放置。 但他們也堅持向左的問題......
import tkinter
window = tkinter.Tk()
frame1 = tkinter.Frame(window).pack()
textbox1 = tkinter.Text(frame1, width=70, height=15).pack(side=tkinter.TOP)
button1 = tkinter.Button(frame1, text="button1").pack(side=tkinter.LEFT)
button2 = tkinter.Button(frame1, text="button2").pack(side=tkinter.LEFT)
button3 = tkinter.Button(frame1, text="button3").pack(side=tkinter.LEFT)
window.mainloop()
在這個例子中,如果我設置另一個框架來分隔小部件......它也沒有到達中心......
import tkinter
window = tkinter.Tk()
frame1 = tkinter.Frame(window).pack(side=tkinter.TOP)
textbox1 = tkinter.Text(frame1, width=70, height=15).pack(side=tkinter.TOP)
frame2 = tkinter.Frame(window).pack(side=tkinter.TOP)
button1 = tkinter.Button(frame2, text="button1").pack(side=tkinter.LEFT)
button2 = tkinter.Button(frame2, text="button2").pack(side=tkinter.LEFT)
button3 = tkinter.Button(frame2, text="button3").pack(side=tkinter.LEFT)
window.mainloop()
在這個例子中。 使用網格,如果我使用不同的框架,按鈕只會跳到文本框上並搞砸一切......
import tkinter
window = tkinter.Tk()
frame0 = tkinter.Frame(window).grid(row=0, column=0)
frame1 = tkinter.Frame(window).grid(row=1, column=0)
textbox = tkinter.Text(frame0, width=70, height=15).grid(row=0, column=0)
button1 = tkinter.Button(frame1, text="button1").grid(row=0, column=0)
button2 = tkinter.Button(frame1, text="button2").grid(row=0, column=1)
button3 = tkinter.Button(frame1, text="button3").grid(row=0, column=2)
window.mainloop()
有人可以向我解釋哪種方式更好使用以及如何更好地理解它......? 它總是讓我感到困惑......
在此先感謝, eliran
我試圖用包或網格來做到這一點。 但我真的很困惑。 我還嘗試將文本框和按鈕放在不同的框架上,所以它可能會將小部件分開並讓我配置它而不會弄亂東西(因為一切都是相對於另一個......)......但我什么都沒有這看起來不錯。
你的第二個例子非常接近工作,但它有一個致命的缺陷。 如果您添加一些調試語句,您會看到frame1
和frame2
是None
。 因此,任何以它們為父的小部件實際上最終都在根 window 中。
這是因為foo().bar()
總是返回.bar()
的結果。 在 tkinter 中, .grid(...)
總是返回None
,所以Frame(...).grid(...)
總是返回None
。
最佳實踐是始終將小部件創建與小部件布局分開。 例如:
frame1 = tkinter.Frame(window)
frame2 = tkinter.Frame(window)
frame1.pack(side="top")
frame2.pack(side="top")
這樣, frame1
和frame2
被正確設置為幀。 發生這種情況時,第二個示例中代碼的 rest 將按預期工作,並且按鈕居中。
在這個例子中。 使用網格,如果我使用不同的框架,按鈕只會跳到文本框上並搞砸一切......
發生這種情況的原因與上面提到的相同:您認為您正在使用單獨的框架,但所有內容都在根 window 中。 因為它們都在根 window 中,並且您將文本小部件和按鈕放在同一行和同一列中,所以它們重疊。
我還想學習如何以正確的方式使用網格,如果我有各種小部件和按鈕,一個在另一個下面沒有“列跨度”,或者調整按鈕內的文本長度以匹配它們上面的小部件......
在這種特定情況下, grid
不是正確的選擇,因為您實際上並沒有創建網格。 你可以使用它,但它比使用pack
需要更多的代碼。 如果您要創建實際的網格, grid
是正確的選擇。 在這種情況下,你不是。
在這種情況下使用grid
需要一點創造力。 雖然這不是唯一的解決方案,但我建議您將底部框架分為五列 - 左右各空一列,中間三列用於按鈕。 空列可用於占用所有額外空間,迫使中間列全部居中。
使用grid
的最佳實踐是每個使用grid
來管理其子級的 window 至少需要具有非零權重的一行和一列。 這讓 tkinter 知道在哪里分配任何額外空間,例如當用戶調整 window 的大小時。
這是使用grid
的完整解決方案:
import tkinter
window = tkinter.Tk()
frame0 = tkinter.Frame(window)
frame1 = tkinter.Frame(window)
window.grid_rowconfigure(0, weight=1)
window.grid_columnconfigure(0, weight=1)
frame0.grid(row=0, column=0, sticky="nsew")
frame1.grid(row=1, column=0, sticky="nsew")
frame0.grid_rowconfigure(0, weight=1)
frame0.grid_columnconfigure(0, weight=1)
textbox = tkinter.Text(frame0, width=70, height=15)
textbox.grid(row=0, column=0, sticky="nsew")
button1 = tkinter.Button(frame1, text="button1")
button2 = tkinter.Button(frame1, text="button2")
button3 = tkinter.Button(frame1, text="button3")
frame1.grid_rowconfigure(0, weight=1)
frame1.grid_columnconfigure((0,4), weight=1)
button1.grid(row=0, column=1)
button2.grid(row=0, column=2)
button3.grid(row=0, column=3)
window.mainloop()
有人可以向我解釋哪種方式更好使用以及如何更好地理解它......?
總之,使用單獨框架的直覺是正確的起點。 您應該將您的 UI 划分為邏輯組,並為每個組使用單獨的框架。 然后,您可以自由地為每個組分別選擇grid
或pack
。 但是,您需要仔細使用grid
,以確保正確使用sticky
選項,並且您已為所有正確的列設置了權重。
最后,您必須從將小部件創建與小部件布局分開的正確做法開始。
我以前也遇到過這類問題。 盡管.pack()
和.grid()
系統非常出色,但當事情變得忙碌時,您可以使用.place()
系統。 .place()
允許您使用 xy 軸坐標精確定位 tkinter 和 ttk 小部件。
坐標 (0,0) 不在中心,而是在 tkinter window 的最左上角。
例如:
some_widget_name = Button(root, text="Click me!"....)
some_widget_name.place(x=100, y=50)
這將使您的小部件向右移動 100 像素,並從最左上角向下移動 50 像素。
但是,有時當您真的想要使小部件的位置精確時,您可能需要進行一些反復試驗以使其在視覺上令人愉悅。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.