2012-03-18 3 views
4

Я пытаюсь создать макет Tkinter, который имеет метки и поля ввода, вертикально выровненные по нескольким окнам LabelFrame.Выравнивание виджета с использованием сетки между несколькими Tkinter LabelFrames

Вот несколько упрощенный код:

#!/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):

Я играл с in_ аргументами до grid(), но не достиг очень многого, и я не могу думать ни о чем другом, чтобы экспериментировать.

ответ

1

Короткий ответ: вы не можете делать то, что хотите. grid не управляет своими строками и столбцами в нескольких контейнерах.

Однако есть, по крайней мере, несколько способов добиться желаемого эффекта. Один из способов - дать первому столбцу в каждом контейнере явную, идентичную ширину. Для этого вы можете использовать метод grid_columnconfigure, чтобы дать каждому столбцу минимальную ширину.

Другим решением является предоставление каждой этикетке одинаковой ширины, которая фактически будет устанавливать ширину первого столбца одинаковой (при условии, что все столбцы в каждом контейнере имеют одинаковый вес).

+0

Есть ли способ определить, какая максимальная ширина всего заданного набора меток? Я бы предпочел написать код, который не требует жесткой кодировки определенной ширины, где мне не нужно, поэтому, если возможно, я хотел бы, чтобы код вычислял правильную ширину для использования. –

+0

@me_and: ну, вы знаете (или можете тривиально вычислить) ширину ваших меток, не так ли? Просто установите все метки на ширину, равную самой широкой этикетке. Или вы можете использовать команды шрифта для определения в пикселях точно, насколько широка будет строка и использовать ее. Вы также можете использовать 'winfo_width' в виджетах, чтобы получить его ширину, хотя часто будет сообщать об этом 1x1, пока виджет не будет отображаться на экране. Если вы хотите получить правильный ответ на этот вопрос, задайте его как отдельный вопрос - комментарии не подходят для лучшего ответа. –

1

Самый простой способ, которым я знаю, чтобы сделать то, что вы хотите, - изменить текстовые переменные Label, а затем проверить 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) 
+0

Я не запускал ваш код, но я думаю, что он не работает, если вы не используете шрифт Mono. Я имею в виду, что OOOOO имеет ту же длину, что и IIIII, но вторая будет намного меньше (в большинстве шрифтов). Кроме того, в вашем примере вы устанавливаете width = 25. Обратите внимание, что 25 символов! = 25 пикселей;) –

Смежные вопросы