Не могу работать с grid
Я хотел создать интерфейс для игры и использовал для этого tkinter. Хотел расставить по таблице, расставил но вышло не так я ожидал.
Вот код:
from tkinter import *
root = Tk()
root.geometry('192x393+500+150')
root.title("Угадай число!")
variant = Entry(root, bg="black",
fg="white",
font="Arial, 30",
justify="center").grid(row=1, columnspan=2)
b1 = Button(text="1").grid(column=0, row=4)
b2 = Button(text="2").grid(column=1, row=4)
b3 = Button(text="3").grid(column=2, row=4)
b4 = Button(text="4").grid(column=0, row=3)
b5 = Button(text="5").grid(column=1, row=3)
b6 = Button(text="6").grid(column=2, row=3)
b7 = Button(text="7").grid(column=0, row=2)
b8 = Button(text="8").grid(column=1, row=2)
b9 = Button(text="9").grid(column=2, row=2)
b0 = Button(text="0").grid(row=5, columnspan=2)
root.mainloop()
Как сейчас выглядеть таблица, а должно быть как в калькуляторе:
Ответы (2 шт):
Никогда не понимал принцип работы колонок и строк в tkinter))
Предлагаю вам, для упрощения работы с кнопками, добавить их в массив, предварительно расставив там в нужном порядке, а затем уже расставить их в цикле.
При этом, строку с установкой размера окна нужно будет убрать: root.geometry('192x393+500+150')
from tkinter import *
root = Tk()
root.title("Угадай число!")
# запрещаем изменять размер окна
root.resizable(width=False, height=False)
variant = Entry(root, bg="black",
fg="white",
font="Arial, 30",
justify="center").grid(row=0, column=0, columnspan=5)
btn_list = [
"1", "2", "3",
"4", "5", "6",
"7", "8", "9",
"0"
]
r = 1
c = 0
for i in btn_list:
Button(root, text=i, width = 10).grid(row=r, column=c)
c += 1
if c > 4:
c = 0
r += 1
root.mainloop()
Получаем такой результат:
Если вам нужен именно ваш размер окна, то нужно просто поменять максимальное количество колонок: в цикле установки кнопок, вместо if c > 4: делаем if c > 1:. В параметре установки поля ввода Entry значение columnspan делаем равным 15
Результат:
Также хотелось бы добавить информацию касательно привязки кнопок к вводу. Сделать это можно через лямбда-функцию.
Для этого переносим размещение variant в отдельную строку
variant = Entry(root, bg="black",fg="white",font="Arial, 30",justify="center")
variant.grid(row=0, column=0, columnspan=5)
Добавляем функцию
def wirte(key):
global memory
variant.insert(END, key)
И в цикле, перед объявлением кнопки определяем её функцию:
cmd = lambda x=i: write(x)
Button(root, text=i, width = 10, command = cmd).grid(row=r, column=c)
Если убрать ограничение по размеру окна, то получится такой результат:
Здесь видно, что текстовое поле расширяет колонки сетки, так что 2 и 3 колонки уезжали за границы окна.
Если для текстового поля задать параметр columnspan=4, то станет немного лучше:
Остается задать для 4-й колонки (на которой нет кнопок, но на нее вылазит текстовое поле) параметр weight=1 ("вес"), чтобы она расширялась (а первые три наоборот сузились, т.к. у них по умолчанию параметр weight=0, колонки с большим "весом" как бы вытесняют колонки с меньшим "весом"):
Код с исправлениями:
from tkinter import *
root = Tk()
# root.geometry('192x393+500+150')
root.title("Угадай число!")
variant = Entry(root, bg="black",
fg="white",
font="Arial, 30",
justify="center").grid(row=1, columnspan=4)
b1 = Button(text="1").grid(column=0, row=4)
b2 = Button(text="2").grid(column=1, row=4)
b3 = Button(text="3").grid(column=2, row=4)
b4 = Button(text="4").grid(column=0, row=3)
b5 = Button(text="5").grid(column=1, row=3)
b6 = Button(text="6").grid(column=2, row=3)
b7 = Button(text="7").grid(column=0, row=2)
b8 = Button(text="8").grid(column=1, row=2)
b9 = Button(text="9").grid(column=2, row=2)
b0 = Button(text="0").grid(row=5, columnspan=2)
root.grid_columnconfigure(3, weight=1)
root.mainloop()
Также учитывайте, что в таких строках:
b1 = Button(text="1").grid(column=0, row=4)
вы в переменную записываете не объект кнопки, а результат вызова метода grid, который всегда None. Чтобы потом не было неожиданностей, нужно сначала записать в переменную кнопку, а потом от переменной вызывать метод grid:
b1 = Button(text="1")
b1.grid(column=0, row=4)
Еще вариант решения проблемы разъезжающихся кнопок без необходимости тонкой настройки сетки - размещать текстовое поле в основном окне, а кнопки в отдельном фрейме, и этот фрейм уже в основном окне:
from tkinter import *
root = Tk()
# root.geometry('192x393+500+150')
root.title("Угадай число!")
variant = Entry(root, bg="black",
fg="white",
font="Arial, 30",
justify="center")
variant.pack()
frame = Frame(root)
Button(frame, text="1").grid(column=0, row=4)
Button(frame, text="2").grid(column=1, row=4)
Button(frame, text="3").grid(column=2, row=4)
Button(frame, text="4").grid(column=0, row=3)
Button(frame, text="5").grid(column=1, row=3)
Button(frame, text="6").grid(column=2, row=3)
Button(frame, text="7").grid(column=0, row=2)
Button(frame, text="8").grid(column=1, row=2)
Button(frame, text="9").grid(column=2, row=2)
Button(frame, text="0").grid(row=5, columnspan=2)
frame.pack()
root.mainloop()
Скриншот:






