在多个Tkinter LabelFrames之间使用网格对齐小部件

4

我将尝试创建一个Tkinter布局,其中包含跨多个LabelFrame框垂直对齐的标签和输入字段。

以下是简化代码:

#!/usr/bin/python
from Tkinter import *

win = Frame()
win.grid(sticky=N+S+E+W)

frame_a = LabelFrame(win, text='Top frame', padx=5, pady=5)
frame_b = LabelFrame(win, text='Bottom frame', padx=5, pady=5)
frame_a.grid(sticky=E+W)
frame_b.grid(sticky=E+W)

for frame in frame_a, frame_b:
    for col in 0, 1, 2:
        frame.columnconfigure(col, weight=1)

Label(win, text='Hi').grid(in_=frame_a, sticky=W)
Label(win, text='Longer label, shorter box').grid(in_=frame_b, sticky=W)

Entry(win).grid(in_=frame_a, row=0, column=1, sticky=W)
Entry(win, width=5).grid(in_=frame_b, row=0, column=1, sticky=W)

win.mainloop()

上面的代码生成一个窗口,看起来像下面这样: Incorrect image produced by above code 然而我想找到一些方法来对齐字段,使窗口看起来更像这样(感谢 MS Paint): Desired image 我已经尝试了使用grid()的in_参数进行调整,但并没有取得太大进展,也想不出其他可以尝试的方法。
2个回答

1

简短的回答是:你无法做到你想要的。 grid 不会跨多个容器管理其行和列。

然而,至少有几种方法可以实现您想要的效果。一种方法是在每个容器中给第一列一个明确的、相同的宽度。为此,您可以使用 grid_columnconfigure 方法为每一列设置最小宽度。

另一种解决方案是给每个标签一个相同的宽度,这将有效地将第一列的宽度设置为相同(假设每个容器中的所有列都具有相同的权重)。


有没有一种方法可以确定给定标签集的所有最大宽度?我更喜欢编写不需要硬编码特定宽度的代码,因此如果可能,我想让代码计算要使用的正确宽度。 - me_and
@me_and:嗯,你知道(或可以轻松计算)标签的宽度,对吧?只需将所有标签设置为与最宽的标签相同的宽度即可。或者,您可以使用字体命令以像素为单位确定字符串的确切宽度并使用它。您还可以在小部件上使用winfo_width来获取其宽度,尽管在小部件实际显示在屏幕上之前,它通常会报告1x1。如果您想要一个正确的答案,请将其作为单独的问题提出--评论不是提供更好答案的正确位置。 - Bryan Oakley

1
我所知道的最简单的方法是更改标签文本变量,然后检查len(txt1)和len(txt2),并将两者的宽度变量设置为最长的一个。以下代码接近于此。我的知识有限,无法确定额外的空格来自何处。
    txt1 = StringVar()
    txt2 = StringVar()
    lblWidth = IntVar()
    txt1 = "Hi"
    txt2 = "Longer label, shorter box"

    if (len(txt1) > len(txt2)):
        lblWidth = len(txt1)
    else:
        lblWidth = len(txt2)

    Label(win, text=txt1, width=lblWidth, anchor=W).grid(in_=frame_a)
    Label(win, text=txt2, width=lblWidth, anchor=W).grid(in_=frame_b, sticky=W)

我没有运行你的代码,但我认为除非你使用Mono字体,否则它不起作用。我的意思是,OOOOO和IIIII具有相同的长度,但第二个会小得多(在大多数字体中)。此外,在你的示例中,你设置了width=25。请注意,25个字符!= 25个像素;) - José Ramón

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接