Не могу работать с 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 шт):

Автор решения: denisnumb

Никогда не понимал принцип работы колонок и строк в 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)
→ Ссылка
Автор решения: insolor

Если убрать ограничение по размеру окна, то получится такой результат:

Скрин 1

Здесь видно, что текстовое поле расширяет колонки сетки, так что 2 и 3 колонки уезжали за границы окна.

Если для текстового поля задать параметр columnspan=4, то станет немного лучше:

Скрин 2

Остается задать для 4-й колонки (на которой нет кнопок, но на нее вылазит текстовое поле) параметр weight=1 ("вес"), чтобы она расширялась (а первые три наоборот сузились, т.к. у них по умолчанию параметр weight=0, колонки с большим "весом" как бы вытесняют колонки с меньшим "весом"):

Скрин 3

Код с исправлениями:

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()

Скриншот:

Скрин альтернативного решения

→ Ссылка