Я хочу сделать мои кнопки сеткой 2 x 2 в нижней части окна с холстом над ними, но кнопки всегда выглядят странно, когда я использую .pack (side = независимо).
Для меня это означает, что у вас явно есть две отдельные области: верхняя область с холстом и нижняя область с кнопками.Первым шагом является создание этих двух областей.Для верхней части просто используйте холст, а для нижней - рамку.
Я собираюсь предположить, что вы хотите, чтобы холст занимал как можно больше места, с кнопками всегда внизу.Для такой компоновки наиболее целесообразно использовать pack
.
Ниже приведена программа с холстом вверху и рамкой внизу для кнопок.Когда вы изменяете размер окна, рамка кнопки остается внизу, а холст заполняет оставшееся пространство:
import tkinter as tk
root = tk.Tk()
canvas = tk.Canvas(root, background="white")
button_frame = tk.Frame(root)
button_frame.pack(side="bottom", fill="x", expand=False)
canvas.pack(side="top", fill="both", expand=True)
# <button code will be added here...>
root.mainloop()
Теперь мы можем сосредоточиться на кнопках.Вам нужны кнопки в сетке 2x2 (хотя у вас есть 5 кнопок ...?), Поэтому естественным выбором будет использование grid
вместо pack
.Мы хотим, чтобы эти кнопки были в нижнем фрейме, поэтому мы задаем этот фрейм в качестве родителя или мастера кнопок.
Вы также несколько любопытно написали «всякий раз, когда окно изменено в размере, кнопки все равно составляют правую область«Хотя раньше вы говорили, что хотите, чтобы они были внизу.Я предполагаю, что вы имеете в виду, что вы хотите, чтобы они были в правом нижнем углу.
Для этого мы создадим сетку с двумя строками и тремя столбцами.Столбец слева будет пустым, и потребуется дополнительное пространство, чтобы заставить кнопки быть справа (конечно, вы можете поместить вещи в этот столбец, если хотите)
Это создает четырекнопки:
attack1 = tk.Button(button_frame, text="Light Attack")
attack2 = tk.Button(button_frame, text="Heavy Attack")
defense1 = tk.Button(button_frame, text="Forcefield")
defense2 = tk.Button(button_frame, text="Heal")
... это заставляет первый столбец расширяться, чтобы заполнить любое дополнительное пространство:
button_frame.grid_columnconfigure(0, weight=1)
... и это размещает их в сетке (это всегдахорошо отделить создание виджета от макета виджета, потому что это упрощает визуализацию макета в коде)
attack1.grid(row=0, column=1, sticky="ew")
attack2.grid(row=0, column=2, sticky="ew")
defense1.grid(row=1, column=1, sticky="ew")
defense2.grid(row=1, column=2, sticky="ew")
Конечный результат таков:
При изменении размера кнопки сохраняют свое относительное положение:
Сводка
Суть этогоэто показать, что вам нужно потратить несколько минут на организацию элементов на экране в логические группы.Существуют разные инструменты макета для решения различных задач (grid
, pack
, place
), и большинство окон получат выгоду от использования правильного инструмента для каждого типа проблемы макета, которую вы пытаетесь решить (pack
- этоподходит для горизонтальной и вертикальной компоновки, grid
подходит для сеток, а place
покрывает несколько крайних случаев, когда необходим идеальный контроль пикселей).