Задать вопрос
@Ledauph1
Я только учусь, не пинайте строго.

Как поместиь виджеты в фрейм (tkinter)?

Не получается разместить виджеты в фрейм.
from tkinter import *

root = Tk()
root.geometry('500x600')

f1 = Frame(root, width=400, height=100, bg="red").pack()
f2 = Frame(root, width=400, height=100, bg="black").pack()
f3 = Frame(root, width=400, height=100, bg="yellow").pack()

b1 = Button(f1, text ='кнопка для фрейма №1', bg ='pink').pack()
b2 = Button(f2, text ='кнопка для фрейма №2', bg ='blue').pack()
b3 = Button(f3, text ='кнопка для фрейма №3', bg ='silver').pack()

root.mainloop()


Результат:
6045596570ac8561879321.jpeg


Нашел такой вариант решения:
from tkinter import *
root=Tk()
frame1=Frame(root,bg='green',bd=100)
frame2=Frame(root,bg='red',bd=100)
button1=Button(frame1,text='Первая кнопка')
button2=Button(frame2,text='Вторая кнопка')
frame1.pack()
frame2.pack()
button1.pack()
button2.pack()
root.mainloop()

Работает, но я не могу задать высоту и ширину фрейма. В чем причина?
  • Вопрос задан
  • 2912 просмотров
Подписаться 1 Простой Комментировать
Решения вопроса 2
@kamenyuga
Не получается разместить виджеты в фрейм

В приведенном коде f1 - это результат вызова метода pack(), который НЕ возвращает ссылку на фрэйм, а возвращает None. Это базовый синтаксис питона, переменной присваивается результат вызова функции.

Не могу задать высоту и ширину фрейма

Документация tk говорит, что "If you want to force the frame to have a specific width, call the .grid_propagate(0) on the widget". По дефолту ткинтер задает всем элементам минимальный требуемый размер, чтобы все поместилось, либо растягивает от минимального размера до размера окна, если указать, как растягивать. Ну, а если места не хватает, то начинаются сжатие, обрезка, невлезание в окно и т.д. В принципе, стандартное поведение многих десктопных гуишек.

Для сколько-нибудь сложного гуи в ткинтере лучше, конечно, использовать .grid(...) - больше строк кода, но более гибкий и контролируемый результат. Грид - это сетка, у нее есть параметр минимального размера строки/столбца.

import * - это плохо.
Ответ написан
Комментировать
@Ledauph1 Автор вопроса
Я только учусь, не пинайте строго.
Нашел решение. Необходимо использовать упаковщик "отдельно" от создания виджета который необходимо поместить в фрейм.
не правильно:
f1 = Frame(root, width=400, height=100, bg="red").pack()

правильно:
f1 = Frame(root, width=400, height=100, bg="red")
f1..pack()

для запрета изменения размера фрейма:
f1.propagate(False)

В целом, код будет выглядеть так:
from tkinter import *

root = Tk()
root.geometry('500x600')

f1 = Frame(root, width=400, height=100, bg="red")
f1.pack()
f1.propagate(False)
f2 = Frame(root, width=400, height=100, bg="black")
f2.pack()
f2.propagate(False)
f3 = Frame(root, width=400, height=100, bg="yellow")
f3.pack()
f3.propagate(False)

b1 = Button(f1, text ='кнопка для фрейма №1', bg ='pink').pack()
b2 = Button(f2, text ='кнопка для фрейма №2', bg ='blue').pack()
b3 = Button(f3, text ='кнопка для фрейма №3', bg ='silver').pack()

root.mainloop()

Результат
606776be275ca194890942.jpeg


Собствено, то что и сказал(а) kamenyuga
В приведенном коде f1 - это результат вызова метода pack(), который НЕ возвращает ссылку на фрэйм, а возвращает None. Это базовый синтаксис питона, переменной присваивается результат вызова функции.

Спасибо, не сразу понял суть(
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы