[英]Tkinter grid spacing problems
我試圖了解tk網格布局是如何工作的,因為界面看起來不像我想象的那樣。 我正在嘗試在同一行上放置一個標簽,后跟兩個按鈕,並在下一行上放置超出標簽寬度和按鈕的樹視圖。 讓它看起來我想要的唯一方法是,如果我為treeview的columnspan使用一個巨大的值。 這是我的代碼:
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
columnHeadings = ("Heading 1", "Heading 2")
def printMsg():
print("Ok")
frame = ttk.Frame(root).grid(row=0, column=0)
label1 = tk.Label(frame, text="Label here").grid(row=0, column=0, columnspan=1)
button1 = tk.Button(frame, text="Yes", width=2, command=printMsg).grid(row=0, column=1)
button2 = tk.Button(frame, text="No", width=2, command=printMsg).grid(row=0, column=2)
#Label and buttons too far apart
#treeview1 = ttk.Treeview(frame, columns=columnHeadings, show='headings').grid(row=1,column=0, columnspan=3)
#Right distance but that's a huge columnspan
treeview1 = ttk.Treeview(frame, columns=columnHeadings, show='headings').grid(row=1,column=0, columnspan=100)
root.mainloop()
當columnspan為3時,第一行在標簽和按鈕之間有很多空格。 當columnspan為100時,標簽和按鈕間距看起來好多了,但我知道這不是正確的方法。 這樣做的正確方法是什么?
在這個小程序中,你有幾件事情密謀反對你。 例如, frame
設置為None
,因此您實際上將所有這些小部件放在根窗口而不是框架中。 這是因為x=y().z()
總是將x
設置為z
的結果,而grid()
總是返回None
。
其次, grid
一個好的經驗法則是你需要給至少一個(通常只有一個)行和一個列來獲得權重,以便tkinter知道如何分配額外的空間。 您還需要使用sticky
選項,以便您的窗口小部件展開以填充已為其提供的空間。 您沒有使用這些技術。
第三,根據我的經驗,我認為當布局語句分散在整個代碼中時,調試布局問題非常困難。 最好將它們完全分組,以便您可以更輕松地查看布局。
grid
解決問題 您可以通過為列3指定權重為1,然后讓樹視圖跨越該列來解決您的問題。 這可以防止按鈕所在的列擴展。 如果您還修復了frame
為None
的問題,並且如果使用適當的sticky
選項,則可以獲得所需的外觀。
這是一個例子:
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
columnHeadings = ("Heading 1", "Heading 2")
def printMsg():
print("Ok")
frame = tk.Frame(root)
frame.grid(row=0, column=0, sticky="nsew")
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
label1 = tk.Label(frame, text="Label here")
button1 = tk.Button(frame, text="Yes", width=2, command=printMsg)
button2 = tk.Button(frame, text="No", width=2, command=printMsg)
treeview1 = ttk.Treeview(frame, columns=columnHeadings, show='headings')
label1.grid(row=0, column=0, columnspan=1)
button1.grid(row=0, column=1)
button2.grid(row=0, column=2)
treeview1.grid(row=1,column=0, columnspan=4, sticky="nsew")
frame.grid_columnconfigure(3, weight=1)
frame.grid_rowconfigure(1, weight=1)
root.mainloop()
pack
所有這一切,我認為有更好的解決方案,而不是試圖讓一切都適合網格。 我的理念是使用正確的工具,在這種情況下,正確的工具是pack
因為它擅長從上到下或從左到右堆疊的東西(反之亦然)。
在您的情況下,您的程序中有兩個不同的區域:頂部的工具欄和下面的樹視圖。 既然這就是你所擁有的,那么使用pack
,將一個放在另一個上面是有意義的。 所以我首先創建兩個框架並打包它們:
toolbar = ttk.Frame(root)
treeframe = ttk.Frame(root)
toolbar.pack(side="top", fill="x")
treeframe.pack(side="bottom", fill="both", expand=True)
現在,您放在toolbar
任何內容都不會影響treeframe
,反之亦然。 你可以自由地在每個框架中做任何你想做的事情。 隨着程序的增長,你會發現擁有不同的區域會使布局問題更容易解決。
由於工具欄包含左對齊的按鈕,因此您也可以使用pack
。 只需確保它們的父項是工具欄框架,您可以像這樣打包它們:
label1 = tk.Label(toolbar, ...)
button1 = tk.Button(toolbar, ...)
button2 = tk.Button(toolbar, ...)
label1.pack(side="left")
button1.pack(side="left")
button2.pack(side="left")
最后,如果您只在底部有一個樹視圖(即:沒有滾動條或其他小部件),您可以使用pack
。 確保它的父級是treeframe
。 如果需要,您可以使用grid
,但pack
更直接。
treeview1.pack(fill="both", expand=True)
關於pack
是你可以真正把所有東西放在一條線上。 您不必采取額外步驟,並給行或列一個權重。
這是一個完整的例子:
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
columnHeadings = ("Heading 1", "Heading 2")
def printMsg():
print("Ok")
toolbar = ttk.Frame(root)
treeframe = ttk.Frame(root)
toolbar.pack(side="top", fill="x")
treeframe.pack(side="bottom", fill="both", expand=True)
label1 = tk.Label(toolbar, text="Label here")
button1 = tk.Button(toolbar, text="Yes", width=2, command=printMsg)
button2 = tk.Button(toolbar, text="No", width=2, command=printMsg)
label1.pack(side="left")
button1.pack(side="left")
button2.pack(side="left")
treeview1 = ttk.Treeview(treeframe, columns=columnHeadings, show='headings')
treeview1.pack(side="top", fill="both", expand=True)
root.mainloop()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.