Как центрировать кадр внутри кадра в Tkinter?

У меня есть фрейм, размер которого я зафиксировал с помощью метода grid_propagate(). Я хотел бы центрировать кадр внутри этого кадра. Как мне это сделать?


person rectangletangle    schedule 21.11.2010    source источник


Ответы (2)


упакуйте его, чтобы заполнить во всех направлениях. Добавьте прокладку по мере необходимости.

Или используйте место, которое позволяет использовать относительное или абсолютное позиционирование. Вы можете использовать относительный x/y 0,5/0,5 и привязку "c" (в центре).

import Tkinter as tk

root=tk.Tk()
f1 = tk.Frame(width=200, height=200, background="red")
f2 = tk.Frame(width=100, height=100, background="blue")

f1.pack(fill="both", expand=True, padx=20, pady=20)
f2.place(in_=f1, anchor="c", relx=.5, rely=.5)

root.mainloop()
person Bryan Oakley    schedule 22.11.2010
comment
Это немного сбивает с толку, так как ни f1, ни f2 не объявляют родителя. Как f1 знает, что нужно запаковать в корень? Кроме того, смешиваются 2 разных менеджера геометрии. Об этом везде предупреждают как о плохой практике. Тем не менее, это работает и решает проблему, с которой я застрял в течение нескольких часов. Так что +1! - person wsaleem; 29.09.2015
comment
@wsaleem: у каждого окна, кроме корневого, должен быть родитель. Корневое окно используется по умолчанию, когда виджет явно не указывает родителя. Что касается смешивания пакетов и мест (и/или сетки): это вполне нормально — даже предпочтительно — в приложении в целом. Вы просто не можете смешивать их в одном содержащем окне. В этом случае f1 управляется корневым окном, а f2f1 (из-за параметра in_. - person Bryan Oakley; 29.09.2015
comment
place() прекрасно, когда вам уже нужно принудительно установить размер внешнего фрейма. Но обычно я избегаю place(), потому что фрейм не определяет размер placed виджетов при автоматическом изменении размера. Пожалуйста, смотрите мой ответ ниже. - person Gary02127; 05.02.2020

Если вы хотите центрировать виджет (например, фрейм) внутри фрейма, проще всего это сделать с помощью .grid(). Если вы используете .pack(), вы застрянете на одном из краев, так как pack() имеет ключевое слово side.

Если вы используете .place(), то вы застряли, форсируя размер внешнего фрейма (что обычно вам не нужно делать, но вы уже сделали это, так что это не проблема), потому что placed виджеты не обнаруживаются когда рамка автоматически изменяется, например, с виджетами packed или gridded. Не знаю почему, но так оно и есть.

Итак, в общем, лучший способ центрировать виджет внутри фрейма — это grid виджета в фрейме. (Опция sticky по умолчанию имеет значение ЦЕНТР.) И затем, если вы хотите иметь возможность изменять размер внешнего фрейма и чтобы виджет оставался в центре, вам нужно разрешить ячейке внешнего фрейма расширяться/расти. Вы бы сделали это с помощью команд .grid_rowconfigure() etc. Итак, примером может быть:

        widget = Widget(frame, ...)
        widget.grid(row=0, column=0, sticky="")
        frame.grid_rowconfigure(0, weight=1)
        frame.grid_columnconfigure(0, weight=1)
person Gary02127    schedule 05.02.2020