@LRei

Позиционирование в tkinter не поддается логике?

нужна помощь с tkinter.
Проблема с позиционированием элементов и отсутствием должной информации о ней. Я пересмотрел и перечитал тонны материалов, но все они по своей сути абсолютно одинаковы и бесполезны.

В нем три типа методов для позиционирования: pack, grid и place. Я никак не могу понять их поведения, особенно grid - он вообще позиционирует элементы как ему вздумается, а смешивать разные виды методов нельзя (ну спасибо, удружили!) Не хочу сильно много расписывать по каждому элементу, я уже по всякому пробовал и ничего не выходит. По логике все в порядке, а поведение совершенно не предсказуемое. Например, четко прописав ширину и высоту элемента, в итоге он окажется совсем другим: прямоугольник вместо квадрата, либо вовсе непонятное нечто.

Вот наглядно:
#Ожидаю квадраты 30х30, размещенные по конкретным координатам
b1 = Button(frame_bot, text="back", bg='gray', width=30, height=30).place(x=5, y=605)
b2 = Button(frame_bot, text="write", bg='blue', width=30, height=30).place(x=45, y=605)
b3 = Button(frame_bot, text="home", bg='green', width=30, height=30).place(x=85, y=605)

По итогу получаю бесконечно идущие вниз полосы, а третья кнопка и вовсе прямоугольная. И куда подевался текст? Логика, ты где?
YwA4YNIeTL6gmDUf-4zuzg.png

Делал по гайду. У них работает, у меня нет. Place() отправляется в мусор. Попробуем pack().
#Ожидаю квадратные кнопки 30х30 с отступами в 5, размещенные во фрейме.
frame_bot = LabelFrame(root, width=360, height=40).pack(padx=5, pady=5, side=BOTTOM)
b1 = Button(frame_bot, text="back", bg='gray', width=30, height=30).pack(padx=5, pady=5, side=LEFT)
b2 = Button(frame_bot, text="write", bg='blue', width=30, height=30).pack(padx=5, pady=5, side=LEFT)
b3 = Button(frame_bot, text="home", bg='green', width=30, height=30).pack(padx=5, pady=5, side=LEFT)

Получаю огромные прямоугольные кнопки, заходящие за экран, спасибо хоть на этот раз с текстом. Я четко указал конкретные размеры, какого черта? Ожидал позиционирование во фрейме (frame_bot, который в этот раз спозиционировался правильно через root (главный метод Tk())), но кнопки избрали свой собственный путь.
63733YAGRD6TAs2owen1-w.png

И зачем нужен этот "root" и его подобные, если это не работает? Пробовал вообще не указывать его и в скобках, как это указывают все в гайдах, но разницы никакой.

С методом grid та же история. Примеров не покажу, уже в прошлом. Позиционирование через проценты корректно не работает, попытки сделать по гайдам не дают результата.

Как работать со всем этим? Логика работы вроде понятна, но программа логике не подчиняется. В играх с внутренней реализацией кодинга (типа Stationeers) все просто и результаты соответствуют ожиданиям, а в этом питоне сидит какой-то черт, который переделывает все по своему и питается злостью новичков.
  • Вопрос задан
  • 453 просмотра
Пригласить эксперта
Ответы на вопрос 1
Vindicar
@Vindicar
RTFM!
Во-первых, нельзя смешивать разные менеджеры в рамках одного контейнера. Если ты этого не понял, я фз что ты читал. Т.е. ты можешь гридом разместить несколько панелей, а потом каждую панель наполнять по-разному.
Во-вторых, стоит чуть-чуть погуглить, и находишь вот такой материал где прямо прописано, что не так со свойством height (ну и width заодно).
Height of the button in text lines (for textual buttons) or pixels (for images).

Решение, мягко говоря, спорное, но оно документировано. Размер виджету нужен только как некоторое предпочтительное значение по умолчанию, так как вообще-то всей геометрией занимается выбранный менеджер геометрии. А раз уж хочешь использовать place, почему ты не обратил внимание на параметры width/height?
В общем, не принимай собственную невнимательность за чужие ошибки.
from tkinter import *

frame_bot = Tk()
frame_bot.geometry("640x480")
# place() возвращает None, как и stack() / grid()
Button(frame_bot, text="back", bg='gray').place(x=5, y=405, width=30, height=30) 
Button(frame_bot, text="write", bg='blue').place(x=45, y=405, width=30, height=30)
Button(frame_bot, text="home", bg='green').place(x=85, y=405, width=30, height=30)

frame_bot.mainloop()
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы