繁体   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