Виджеты Button, Label, Entry
В этом уроке рассмотрим подробнее три наиболее простых и часто используемых виджета GUI – кнопку, метку и однострочное текстовое поле. В tkinter объекты этих элементов интерфейса порождаются соответственно от классов Button , Label и Entry .
Свойства и методы виджетов бывают относительно общими, характерными для многих типов, а также частными, зачастую встречающимися только у какого-то одного класса. В любом случае список настраиваемых свойств велик. В этом курсе мы будем рассматривать только ключевые свойства и методы классов пакета tkinter .
В Tkinter существует три способа конфигурирования свойств виджетов:
- в момент создания объекта,
- с помощью метода config , он же configure ,
- путем обращения к свойству как к элементу словаря.
Button – кнопка
Самыми важными свойствами виджета класса Button являются text , с помощью которого устанавливается надпись на кнопке, и command для установки действия, то есть того, что будет происходить при нажатии на кнопку.
По умолчанию размер кнопки соответствует ширине и высоте текста, однако с помощью свойств width и height эти параметры можно изменить. Единицами измерения в данном случае являются знакоместа (количество символов).
Такие свойства как bg , fg , activebackground и activeforeground определяют соответственно цвет фона и текста, цвет фона и текста во время нажатия и установки курсора мыши над кнопкой.
from tkinter import * def change(): b1['text'] = "Изменено" b1['bg'] = '#000000' b1['fg'] = '#ffffff' b1['activebackground'] = '#555555' b1['activeforeground'] = '#ffffff' root = Tk() b1 = Button(text="Изменить", width=15, height=3) b1.config(command=change) b1.pack() root.mainloop()
Здесь значение свойства command устанавливается с помощью метода config . Однако можно было сделать и так: b1[‘command’] = change . Вот так будет выглядеть кнопка после запуска программы и после нажатия на нее:

Label – метка
Виджет Label просто отображает текст в окне и служит в основном для информационных целей (вывод сообщений, подпись других элементов интерфейса). Свойства метки во многом схожи с таковыми у кнопки. Однако у меток нет опции command . Поэтому связать их с событием можно только с помощью метода bind .
На примере объекта типа Label рассмотрим свойство font – шрифт.
from tkinter import * root = Tk() l1 = Label(text="Машинное обучение", font="Arial 32") l2 = Label(text="Распознавание образов", font=("Comic Sans MS", 24, "bold")) l1.config(bd=20, bg='#ffaaaa') l2.config(bd=20, bg='#aaffff') l1.pack() l2.pack() root.mainloop()
Значение шрифта можно передать как строку или как кортеж. Второй вариант удобен, если имя шрифта состоит из двух и более слов. После названия шрифта можно указать размер и стиль.
Также как font свойство bd есть не только у метки. С его помощью регулируется размер границ. Здесь единицей измерения является пиксель.

Бывает, что метки и кнопки не присваивают переменным, если потом к ним в коде не приходится обращаться. Их создают от класса и сразу размещают:
from tkinter import * def take(): lab['text'] = "Выдано" root = Tk() Label(text="Пункт выдачи").pack() Button(text="Взять", command=take).pack() lab = Label(width=10, height=1) lab.pack() root.mainloop()
В данном примере только у одной метки есть связь с переменной, так как одно из ее свойств может быть изменено в процессе выполнения программы.
Entry – однострочное текстовое поле
Текстовые поля предназначены для ввода информации пользователем. Однако нередко также для вывода, если предполагается, что текст из них будет скопирован. Текстовые поля как элементы графического интерфейса бывают однострочными и многострочными. В tkinter вторым соответствует класс Text , который будет рассмотрен позже.
Свойства экземпляров Entry во многом схожи с двумя предыдущими виджетами. А вот методы – нет. Из текстового поля можно взять текст. За это действие отвечает метод get . В текстовое поле можно вставить текст методом insert . Также можно удалить текст методом delete .
Метод insert принимает позицию, в которую надо вставлять текст, и сам текст. Такой код
from tkinter import * from datetime import datetime as dt def insert_time(): t = dt.now().time() e1.insert(0, t.strftime('%H:%M:%S ')) root = Tk() e1 = Entry(width=50) but = Button(text="Время", command=insert_time) e1.pack() but.pack() root.mainloop()
приведет к тому, что после каждого нажатия на кнопку будет вставляться новое время перед уже существующей в поле строкой.

Если 0 в insert заменить на константу END , то вставляться будет в конец. Можно указать любое число-индекс знакоместа, тогда вставка будет производиться куда-либо в середину строки.
Метод delete принимает один или два аргумента. В первом случае удаляется один символ в указанной позиции. Во втором – срез между двумя указанными индексами, не включая последний. Если нужно полностью очистить поле, то первым аргументом должен быть 0, вторым – END .
Практическая работа
Напишите программу, состоящую из семи кнопок, цвета которых соответствуют цветам радуги. При нажатии на ту или иную кнопку в текстовое поле должен вставляться код цвета, а в метку – название цвета.
Коды цветов в шестнадцатеричной кодировке: #ff0000 – красный, #ff7d00 – оранжевый, #ffff00 – желтый, #00ff00 – зеленый, #007dff – голубой, #0000ff – синий, #7d00ff – фиолетовый.
Примерно должно получиться так:

Для выравнивания строки по центру в текстовом поле используется свойство justify со значением CENTER .
Курс с примерами решений практических работ: pdf-версия
X Скрыть Наверх
Tkinter. Программирование GUI на Python
Python-сообщество
![]()
- Начало
- » GUI
- » Tkinter.ttk выравнивание текста в Label по правому краю
#1 Май 17, 2015 20:56:39
Andrew22528 Зарегистрирован: 2015-05-17 Сообщения: 44 Репутация: 0 Профиль Отправить e-mail
Tkinter.ttk выравнивание текста в Label по правому краю
Всем привет! Скажите пожалуйста, как сделать выравнивание текста в Label по правому краю.
#2 Май 17, 2015 21:28:18
4kpt_III Зарегистрирован: 2014-12-22 Сообщения: 999 Репутация: 39 Профиль Отправить e-mail
Tkinter.ttk выравнивание текста в Label по правому краю
#3 Май 17, 2015 21:50:21
Andrew22528 Зарегистрирован: 2015-05-17 Сообщения: 44 Репутация: 0 Профиль Отправить e-mail
Tkinter.ttk выравнивание текста в Label по правому краю

Пробовал, не получается
#4 Май 17, 2015 21:56:57
4kpt_III Зарегистрирован: 2014-12-22 Сообщения: 999 Репутация: 39 Профиль Отправить e-mail
Tkinter.ttk выравнивание текста в Label по правому краю
Вы уверены, что объект по ширине расположен. Сделайте bg=“red” и увидите реальные размеры объекта. Текст, естественно, можно располагать только учитывая реальные размеры.
Создание макетов окна / tkinter 5
Виджеты определяют, какие действия смогут выполнять пользователи с помощью графического интерфейса. Однако важно обращать внимание на их взаимное и индивидуальное расположение. Эффективные макеты позволяют интуитивно определять значение и приоритетность каждого графического элемента, так что пользователь способен быстро разобраться, как нужно взаимодействовать с программой.
Макет также определяет внешний вид, который должен прослеживаться во всем приложении. Например, если кнопки расположены в правом верхнем углу, то они должны находиться там всегда. Хотя это может казаться очевидным для разработчиков, конечные пользователи будут путаться, если не провести их по приложению.
В этом материале погрузимся в разные механизмы, которые Tkinter предлагает для формирования макета, группировки виджетов и управления другими атрибутами, например, размером и отступами.
Группировка виджетов с фреймами
Фрейм представляет собой прямоугольную область окна, обычно используемую в сложных макетах. В них содержатся другие виджеты. Поскольку у фреймов есть собственные внутренние отступы, рамки и фон, то нужно отметить, что группа виджетов связана логически.
Еще одна распространенная особенность фреймов — инкапсуляция части функциональности приложения таким образом, что с помощью абстракции можно спрятать детали реализации дочерних виджетов.
Дальше будут рассмотрены оба сценария на примере создания компонента, который наследует класс Frame и раскрывает определенную информацию о включенных виджетах.
Создадим приложение, которое будет включать два списка, где первый — это список элементов, а второй изначально пустой. Оба можно пролистывать. Также есть возможность перемещать элементы между ними с помощью двух кнопок по центру:

Определим подкласс Frame , который представляет собой список с возможностью скроллинга и два его экземпляра. Также в основное окно будут добавлены две кнопки:
import tkinter as tk class ListFrame(tk.Frame):
def __init__(self, master, items=[]):
super().__init__(master)
self.list = tk.Listbox(self)
self.scroll = tk.Scrollbar(self, orient=tk.VERTICAL,
command=self.list.yview)
self.list.config(yscrollcommand=self.scroll.set)
self.list.insert(0, *items)
self.list.pack(side=tk.LEFT)
self.scroll.pack(side=tk.LEFT, fill=tk.Y)
def pop_selection(self):
index = self.list.curselection()
if index:
value = self.list.get(index)
self.list.delete(index)
return value
def insert_item(self, item):
self.list.insert(tk.END, item) class App(tk.Tk):
def __init__(self):
super().__init__()
months = ["Январь", "Февраль", "Март", "Апрель",
"Май", "Июнь", "Июль", "Август", "Сентябрь",
"Октябрь", "Ноябрь", "Декабрь"]
self.frame_a = ListFrame(self, months)
self.frame_b = ListFrame(self)
self.btn_right = tk.Button(self, text ,
command=self.move_right)
self.btn_left = tk.Button(self, text , command=self.move_left) self.frame_a.pack(side=tk.LEFT, padx=10, pady=10) self.frame_b.pack(side=tk.RIGHT, padx=10, pady=10) self.btn_right.pack(expand=True, ipadx=5) self.btn_left.pack(expand=True, ipadx=5)
def move_right(self):
self.move(self.frame_a, self.frame_b) def move_left(self):
self.move(self.frame_b, self.frame_a)
def move(self, frame_from, frame_to):
value = frame_from.pop_selection()
if value:
frame_to.insert_item(value) if __name__ == "__main__":
app = App()
app.mainloop()Как работает группировка виджетов
У класса ListFrame есть только два метода для взаимодействия с внутренним списком: pop_selection() и insert_item() . Первый возвращает и удаляет текущий выделенный элемент, или не делает ничего, если элемент не был выбран. Второй — вставляет элемент в конец списка.
Эти методы используются в родительском классе для перемещения элемента из одного списка в другой:
def move(self, frame_from, frame_to):
value = frame_from.pop_selection()
if value:
frame_to.insert_item(value)Также можно воспользоваться особенностями контейнеров родительского фрейма, чтобы правильно размещать их с нужными внутренними отступами:
# .
self.frame_a.pack(side=tk.LEFT, padx=10, pady=10)
self.frame_b.pack(side=tk.RIGHT, padx=10, pady=1Благодаря фреймам вызовы управлять геометрией макетов проще.
Еще одно преимущество такого подхода — возможность использовать geometry manager в контейнерах каждого виджета. Это могут быть grid() для виджетов во фрейме или pack() для укладывания фрейма в основном окне.
Однако смешивать эти менеджеры в одном контейнере в Tkinter запрещено. Из-за этого приложение просто не будет работать.
Geometry manager Pack
В прошлых материалах можно было обратить внимание на то, что после создания виджета он не отображается на экране автоматически. Для каждого нужно было вызывать метод pack() . Это подразумевает использование соответствующего geometry manager.
Это один из трех доступных в Tkinter менеджеров и он отлично подходит для простых макетов, как в случае, когда, например, нужно разместить все друг над другом или рядом.
Предположим, что нужно получить следующий макет для приложения:
Он состоит из трех строк, где в последней есть три виджета, расположенных рядом друг с другом. В таком случае Pack сможет добавить виджеты как требуется без использования дополнительных фреймов.
Для этого будут использоваться пять виджетов Label с разными текстом и фоном, что поможет различать каждую прямоугольную область:
import tkinter as tk
class App(tk.Tk):
def __init__(self):
super().__init__()
label_a = tk.Label(self, text="Label A", bg="yellow")
label_b = tk.Label(self, text="Label B", bg="orange")
label_c = tk.Label(self, text="Label C", bg="red")
label_d = tk.Label(self, text="Label D", bg="green")
label_e = tk.Label(self, text="Label E", bg="blue")
opts = < 'ipadx': 10, 'ipady': 10, 'fill': tk.BOTH >
label_a.pack(side=tk.TOP, **opts)
label_b.pack(side=tk.TOP, **opts)
label_c.pack(side=tk.LEFT, **opts)
label_d.pack(side=tk.LEFT, **opts)
label_e.pack(side=tk.LEFT, **opts)
if __name__ == "__main__":
app = App()
app.mainloop()Также были добавлены параметры в словаре opts . Они делают яснее размеры каждой области:
Как работает Pack
Чтобы лучше понимать принципы работы Pack, разберем пошагово, как виджеты добавляются в родительский контейнер. Стоит обратить особое внимание на значение параметра side , который определяет относительное положение виджета по отношению к следующему в этом же контейнере.
Сначала добавляются две метки в верхней части экрана. Пусть значение параметра side по умолчанию является tk.TOP ,все равно зададим его явно, чтобы отличать от тех случаев, где используется tk.LEFT :
Дальше добавляем еще три метки со значением tk.LEFT у параметра side , в результате чего они размещаются рядом друг рядом с другом:
Определение стороны label_e особой роли не играет, поскольку это последний виджет, который добавляется в контейнер.
Важно запомнить, что это основная причина, почему порядок так важен при работе с Pack. Чтобы не столкнутся с непредвиденными результатами в сложных макетах распространенной практикой считается их расположение в пределах фрейма так, что бы они не пересекались.
В таких случаях рекомендуется использовать geometry manager Grid, поскольку он позволяет прямо задавать положение каждого виджета с помощью вызова geometry manager и избегать использования дополнительных фреймов.
В side можно передать не только tk.TOP и tk.LEFT , но также tk.BOTTOM и tk.RIGHT . Они разместят виджеты в другом порядке, но это может быть не интуитивно, ведь мы естественным путем следим сверху вниз и слева направо.
Например, если заменить значение tk.LEFT на tk.RIGHT в последних трех виджетах, их порядок будет следующим: label_e , label_d и label_c .
Geometry manager Grid
Grid — самый гибкий из всех доступных geometry manager. Он полностью переосмысливает концепцию сетки (grid), которая традиционно используется при дизайне пользовательских интерфейсов. Сетка — это двумерная таблица, разделенная на строки и колонки, где каждая ячейка представляет собой пространство, которое доступно для виджета.
Продемонстрируем работу Grid с помощью следующего макета:
Его можно представить в виде таблицы 3×3, где виджеты во второй и третьей колонках растягиваются на две строки, а виджет в третьей строке занимает все три колонки.
Как и в предыдущем варианте используем 5 меток с разным фоном, чтобы проиллюстрировать распределение ячеек:
import tkinter as tk class App(tk.Tk):
def __init__(self):
super().__init__()
label_a = tk.Label(self, text="Label A", bg="yellow")
label_b = tk.Label(self, text="Label B", bg="orange")
label_c = tk.Label(self, text="Label C", bg="red")
label_d = tk.Label(self, text="Label D", bg="green")
label_e = tk.Label(self, text="Label E", bg="blue")
opts = < 'ipadx': 10, 'ipady': 10 , 'sticky': 'nswe' >
label_a.grid(row=0, column=0, **opts)
label_b.grid(row=1, column=0, **opts)
label_c.grid(row=0, column=1, rowspan=2, **opts)
label_d.grid(row=0, column=2, rowspan=2, **opts)
label_e.grid(row=2, column=0, columnspan=3, **opts) if __name__ == "__main__":
app = App()
app.mainloop()Также будем передавать словарь параметров, включающий внутренний отступ, который растянет виджеты на все доступное пространство внутри ячеек.
Как работает Grid
Расположение label_a и label_b говорит само за себя: они занимают первую и вторую строки первой колонки соответственно (важно не забывать, что индексация начинается с нуля):
Чтобы растянуть label_c и label_d на несколько ячеек, зададим значение 2 для параметра rowspan . Таким образом они будут занимать две ячейки, начиная с положения, отмеченного опциями row и column . Наконец, значение columnspan для label_e будет 3.
Важно запомнить, что в отличие от Pack есть возможность менять порядок вызовов к grid() для каждого виджета без изменения финального макета.
Параметр sticky определяет границы, к которым виджет должен крепиться. Он выражается в координатах сторон света: север, юг, запад и восток. В Tkinter эти значения выражены константами tk.N , tk.S , tk.W и tk.E , а также их комбинациями: tk.NW , tk.NE , tk.SW и tk.SE .
Например, sticky=tk.N выравнивает виджет у верхней границы ячейки (north – север), а sticky=tk.SE — в правом нижнем углу (south-ease – юго-восток).
Поскольку эти константы представляют соответствующие символы в нижнем регистре, выражение tk.N + tk.S + tk.W + tk.E можно записать в виде строки nwse . Это значит, что виджет должен расширяться одновременно горизонтально и вертикально — по аналогии с работой fill=tk.BOTH из Pack.
Если параметру sticky значение не передается, виджет располагается по центру ячейки.
Geometry manager Place
Менеджер Place позволяет задать положение и размер виджета в абсолютном или относительном значении.
Из трех менеджеров этот является наименее используемым. С другой стороны, он может работать со сложными сценариями, где есть необходимость свободно разместить виджет или перекрыть другой.
Для демонстрации работы Place повторим следующий макет, смешав абсолютные и относительные положения и размеры:
Метки, которые будут отображаться, имеют разный фон и определены в том порядке, в котором они будут расположены слева направо и сверху вниз:
import tkinter as tk
class App(tk.Tk):
def __init__(self):
super().__init__()
label_a = tk.Label(self, text="Label A", bg="yellow")
label_b = tk.Label(self, text="Label B", bg="orange")
label_c = tk.Label(self, text="Label C", bg="red")
label_d = tk.Label(self, text="Label D", bg="green")
label_e = tk.Label(self, text="Label E", bg="blue")
label_a.place(relwidth=0.25, relheight=0.25)
label_b.place(x=100, anchor=tk.N,
width=100, height=50)
label_c.place(relx=0.5, rely=0.5, anchor=tk.CENTER,
relwidth=0.5, relheight=0.5)
label_d.place(in_=label_c, anchor=tk.N + tk.W,
x=2, y=2, relx=0.5, rely=0.5,
relwidth=0.5, relheight=0.5)
label_e.place(x=200, y=200, anchor=tk.S + tk.E,
relwidth=0.25, relheight=0.25)
if __name__ == "__main__":
app = App()
app.mainloop()Если запустить эту программу, то можно будет увидеть наложение label_c и label_d в центре экрана. Этого не удастся добиться с помощью других менеджеров.
Как работает Place
Первая метка располагается со значением 0.25 у параметров relwidth и relheight . Это значит, что виджет будет занимать 25% ширины и высоты родительского. По умолчанию виджеты расположены в положениях x=0 и y=0 , а также выравнены к северо-западу, то есть, верхнему левому углу экрана.
Вторая метка имеет абсолютное положение — x=100 . Она выравнена по верхней границе с помощью параметра anchor , который имеет значение tk.N . Тут также определен абсолютный размер с помощью width и height .
Третья метка расположена по центру окна с помощью относительного позиционирования и параметра anchor для tk.CENTER . Важно запомнить, что значение 0.5 для relx и relwidth обозначает половину родительской ширины, а 0.5 для rely и relheight — половину родительской высоты.
Четвертая метка расположена в верхней части label_c . Это делается с помощью переданного аргумента in_ (суффикс используется из-за того, что in — зарезервированное ключевое слово в Python). При использовании in_ можно обратить внимание на то, что выравнивание не является геометрически точным. В этом примере нужно добавить смещение на 2 пикселя в каждом направлении, чтобы идеально перекрыть правый нижний угол label_c .
Наконец, пятая метка использует абсолютное позиционирование и относительный размер. Как можно было заметить, эти размеры легко переключаются, поскольку значение размера родительского контейнера предполагается (200 х 200 пикселей). Однако при изменении размера основного окна будут работать только относительные величины. Это поведение легко проверить.
Еще одно важное преимущество Place — возможность совмещать его с Pack и Grid.
Например, представьте, что есть необходимость динамически отобразить текст на виджете при нажатии правой кнопкой мыши на нем. Его можно представить в виде виджета Label, который располагается в относительном положении при нажатии:
Лучше всего использовать другие менеджеры в своих приложениях Tkinter, а специализированные оставить для случаев, когда нужно кастомное позиционирование.
Группировка полей ввода с помощью виджета LabelFrame
Класс LabelFrame может быть использован для группировки нескольких виджетов ввода. Он представляет собой логическую сущность с соответствующей меткой. Обычно он используется в формах и сильно напоминает виджет Frame .
Создадим форму с парой экземпляров LabelFrame , каждый из которых будет включать соответствующие виджеты ввода:
Поскольку цель этого примера — показать финальный макет, добавим некоторые виджеты без сохранения их ссылок в виде атрибутов:
Виджет Tkinter Label в Python
Виджет Tkinter Label в Python используется для указания метки контейнера, в котором мы можем разместить текст или изображения. Этот виджет используется для сообщения пользователю о других виджетах, используемых в приложении Python.
Существуют различные параметры, которые можно указать для настройки текста или части текста, отображаемого в метке.
Синтаксис для использования метки приведен ниже.
w = Label(master, options)Список возможных вариантов приведен ниже.
| № | Вариант | Описание |
|---|---|---|
| 1 | anchor | Он определяет точное положение текста в пределах размера, предоставленного виджету. Значение по умолчанию – ЦЕНТР, которое используется для центрирования текста в указанном пространстве. |
| 2 | bg | Цвет фона, отображаемый за виджетом. |
| 3 | bitmap | Используется для установки растрового изображения в указанный графический объект, чтобы метка могла представлять графику вместо текста. |
| 4 | bd | Представляет ширину границы. По умолчанию – 2 пикселя. |
| 5 | cursor | Указатель мыши изменится на указанный тип курсора, то есть стрелка, точка и т. д. |
| 6 | font | Тип шрифта текста, написанного внутри виджета. |
| 7 | fg | Цвет переднего плана текста, написанного внутри виджета. |
| 8 | height | Высота виджета. |
| 9 | image | Изображение, которое будет отображаться как метка. |
| 10 | justify | Он используется для представления ориентации текста, если текст содержит несколько строк. Он может быть установлен на ВЛЕВО для выравнивания по левому краю, ВПРАВО для выравнивания по правому краю и ЦЕНТР для выравнивания по центру. |
| 11 | Padx | Горизонтальный отступ текста. Значение по умолчанию – 1. |
| 12 | pady | Вертикальный отступ текста. Значение по умолчанию – 1. |
| 13 | relief | Тип границы. Значение по умолчанию – FLAT. |
| 14 | text | Задается строковая переменная, которая может содержать одну или несколько строк текста. |
| 15 | textvariable | Текст, записанный внутри виджета, устанавливается в управляющую переменную StringVar, чтобы к нему можно было получить доступ и изменить его соответствующим образом. |
| 16 | underline | Мы можем отобразить строку под указанной буквой текста. Установите этот параметр на номер буквы, под которой будет отображаться строка. |
| 17 | width | Ширина виджета. Указывается как количество символов. |
| 18 | wraplength | Вместо того, чтобы использовать только одну строку в качестве текста метки, мы можем разбить ее на количество строк, где каждая строка имеет количество символов, указанное в этой опции. |
Пример
# !/usr/bin/python3 from tkinter import * top = Tk() top.geometry("400x250") #creating label uname = Label(top, text = "Username").place(x = 30,y = 50) #creating label password = Label(top, text = "Password").place(x = 30, y = 90) sbmitbtn = Button(top, text = "Submit",activebackground = "pink", activeforeground = "blue").place(x = 30, y = 120) e1 = Entry(top,width = 20).place(x = 100, y = 50) e2 = Entry(top, width = 20).place(x = 100, y = 90) top.mainloop()







