簡體   English   中英

Tkinter網格間距問題

[英]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,然后讓樹視圖跨越該列來解決您的問題。 這可以防止按鈕所在的列擴展。 如果您還修復了frameNone的問題,並且如果使用適當的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM