tkinter - понимание пакета и сетки - простой макет. (всегда смущает ...) - PullRequest
0 голосов
/ 18 июня 2020

Я пытаюсь настроить текстовое поле и под ним 3 кнопки в строке по центру. Я не хочу расширять их, чтобы заполнить всю область. просто будьте в центре, чтобы оставаться в исходном размере.

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

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

В этом примере. Как я могу центрировать кнопки? Мне нужно использовать side = tkinter.LEFT, чтобы ставить их один за другим подряд. но проблема в том, что они также придерживаются влево ...

import tkinter

window = tkinter.Tk()

frame1 = tkinter.Frame(window).pack()

textbox1 = tkinter.Text(frame1, width=70, height=15).pack(side=tkinter.TOP)

button1 = tkinter.Button(frame1, text="button1").pack(side=tkinter.LEFT)
button2 = tkinter.Button(frame1, text="button2").pack(side=tkinter.LEFT)
button3 = tkinter.Button(frame1, text="button3").pack(side=tkinter.LEFT)

window.mainloop()

в этом примере, если я установил другой кадр для разделения между виджетами ... Он также не попадает в центр ....

import tkinter

window = tkinter.Tk()

frame1 = tkinter.Frame(window).pack(side=tkinter.TOP)

textbox1 = tkinter.Text(frame1, width=70, height=15).pack(side=tkinter.TOP)

frame2 = tkinter.Frame(window).pack(side=tkinter.TOP)

button1 = tkinter.Button(frame2, text="button1").pack(side=tkinter.LEFT)
button2 = tkinter.Button(frame2, text="button2").pack(side=tkinter.LEFT)
button3 = tkinter.Button(frame2, text="button3").pack(side=tkinter.LEFT)

window.mainloop()

А в этом примере. с сеткой, если я использую разные фреймы, кнопка просто прыгает в текстовое поле и все перепутывает ....

import tkinter

window = tkinter.Tk()

frame0 = tkinter.Frame(window).grid(row=0, column=0)

frame1 = tkinter.Frame(window).grid(row=1, column=0)

textbox = tkinter.Text(frame0, width=70, height=15).grid(row=0, column=0)

button1 = tkinter.Button(frame1, text="button1").grid(row=0, column=0)
button2 = tkinter.Button(frame1, text="button2").grid(row=0, column=1)
button3 = tkinter.Button(frame1, text="button3").grid(row=0, column=2)

window.mainloop()

Может кто-нибудь объяснить мне, пожалуйста, каким образом лучше использовать и как чтобы лучше понять ...? это всегда меня смущает ...

заранее спасибо, Элиран

Ответы [ 2 ]

0 голосов
/ 18 июня 2020

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

Ваш второй пример довольно близок к рабочему, но он имеет фатальный недостаток. Если вы добавите несколько операторов отладки, вы увидите, что 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 используется правильно и что вы установили веса для всех правильных столбцов.

И, наконец, вы должны начните с надлежащей практики отделения создания виджета от макета виджета.

0 голосов
/ 18 июня 2020

У меня уже были такие проблемы раньше. Несмотря на то, что системы .pack() и .grid() превосходны, когда все становится hecti c, вы можете использовать систему .place(). .place() позволяет точно определить ваши виджеты tkinter и ttk, используя координаты оси xy.

Координаты (0,0) находятся не в центре, а в верхнем левом углу вашего окна tkinter.

Например:

some_widget_name = Button(root, text="Click me!"....)
some_widget_name.place(x=100, y=50)

Это заставит ваш виджет перемещаться на 100 пикселей вправо и на 50 пикселей вниз от самого верхнего левого угла.

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

...