Пытался сделать паком или сеткой. но я действительно запуталась. Я также пытаюсь поместить текстовое поле и кнопки в другой фрейм, чтобы, возможно, он разделил виджеты и позволил мне настроить его, не испортив вещи (потому что все относительно другого ..) ... но у меня ничего не было это выглядит хорошо.
Ваш второй пример довольно близок к рабочему, но он имеет фатальный недостаток. Если вы добавите несколько операторов отладки, вы увидите, что frame1
и frame2
равны None
. Таким образом, любые виджеты с такими родительскими элементами фактически оказываются в окне root.
Это потому, что foo().bar()
всегда возвращает результат .bar()
. В tkinter .grid(...)
всегда возвращает None
, поэтому Frame(...).grid(...)
всегда будет возвращать None
.
Лучше всего всегда отделять создание виджета от макета виджета. Например:
frame1 = tkinter.Frame(window)
frame2 = tkinter.Frame(window)
frame1.pack(side="top")
frame2.pack(side="top")
При этом frame1
и frame2
правильно установлены в кадры. И когда это происходит, остальная часть кода во втором примере работает так, как вы ожидаете, а кнопки центрированы.
И в этом примере. с сеткой, если я использую разные фреймы, кнопка просто прыгает в текстовое поле и все испортила ....
Это происходит по той же причине, что упомянута выше: вы думаете вы используете отдельные фреймы, но все происходит в окне root. Поскольку все они находятся в окне root, и вы помещаете текстовый виджет и кнопку в одну строку и столбец, они перекрываются.
Я также хочу узнать, как правильно использовать сетку, если у меня есть все виды виджетов и кнопок, расположенные один под другим без "размаха столбцов", или настроить длину текста внутри кнопок. чтобы соответствовать виджетам над ними ...
grid
не является правильным выбором в этом конкретном c случае, поскольку вы фактически не создаете сетку. Вы можете использовать его, но для этого требуется больше кода, чем при использовании pack
. grid
- правильный выбор, если вы создаете настоящую сетку. В данном случае это не так.
Использование grid
в этом случае требует небольшого творчества. Хотя это не единственное решение, я бы порекомендовал вам разделить нижний фрейм на пять столбцов - пустой столбец слева и справа и три столбца посередине для кнопок. Пустые столбцы могут использоваться для заполнения всего дополнительного места, заставляя все средние столбцы центрироваться. как минимум одна строка и один столбец с ненулевым весом. Это позволяет tkinter узнать, где выделить дополнительное пространство, например, когда пользователь изменяет размер окна.
Вот полное решение с использованием grid
:
import tkinter
window = tkinter.Tk()
frame0 = tkinter.Frame(window)
frame1 = tkinter.Frame(window)
window.grid_rowconfigure(0, weight=1)
window.grid_columnconfigure(0, weight=1)
frame0.grid(row=0, column=0, sticky="nsew")
frame1.grid(row=1, column=0, sticky="nsew")
frame0.grid_rowconfigure(0, weight=1)
frame0.grid_columnconfigure(0, weight=1)
textbox = tkinter.Text(frame0, width=70, height=15)
textbox.grid(row=0, column=0, sticky="nsew")
button1 = tkinter.Button(frame1, text="button1")
button2 = tkinter.Button(frame1, text="button2")
button3 = tkinter.Button(frame1, text="button3")
frame1.grid_rowconfigure(0, weight=1)
frame1.grid_columnconfigure((0,4), weight=1)
button1.grid(row=0, column=1)
button2.grid(row=0, column=2)
button3.grid(row=0, column=3)
window.mainloop()
Может кто-нибудь объяснить мне, пожалуйста, каким образом лучше использовать и как это лучше понять ...?
Таким образом, ваш инстинкт использовать отдельные фреймы - это правильное место для начала. Вы должны разделить свой пользовательский интерфейс на логические группы и использовать отдельные фреймы для каждой группы. Затем вы можете выбрать grid
или pack
для каждой группы отдельно. Однако вам нужно быть внимательными с grid
, чтобы убедиться, что опция sticky
используется правильно и что вы установили веса для всех правильных столбцов.
И, наконец, вы должны начните с надлежащей практики отделения создания виджета от макета виджета.