tkinter — интерфейс Python к Tcl/Tk
Исходный код: Lib/tkinter/__init__.py
Пакет tkinter («интерфейс Tk») — это стандартный интерфейс Python к набору средств создания графических интерфейсов Tcl/Tk. И Tk, и tkinter доступны на большинстве платформ Unix, включая macOS, а также в системах Windows.
Запуск python -m tkinter из командной строки должен открыть окно с демонстрацией простого интерфейса Tk. Это позволит убедиться, что tkinter правильно установлена в вашей системе, а также узнать установленную версию Tcl/Tk и прочитать документацию Tcl/Tk, относящуюся к этой версии.
Tkinter поддерживает различные версии Tcl/Tk, собранные как с поддержкой потоков, так и без неё. Официальный бинарный выпуск Python поставляется с Tcl/Tk 8.6 с поддержкой потоков. Дополнительную информацию о поддерживаемых версиях см. в исходном коде модуля _tkinter.
Tkinter — это не тонкая оболочка: он добавляет значительный объём собственной логики, чтобы сделать работу с ним более удобной для Python-разработчиков. В этой документации основное внимание уделяется этим дополнениям и изменениям; за сведениями о неизменённых аспектах мы отсылаем к официальной документации Tcl/Tk.
Примечание
В Tcl/Tk 8.5 (2007) появился современный набор тематических компонентов пользовательского интерфейса и новый API для работы с ними. Доступны как старый, так и новый API. В большинстве материалов, которые можно найти в интернете, по-прежнему используется старый API, поэтому они могут быть сильно устаревшими.
См. также
-
- TkDocs
-
Подробное руководство по созданию пользовательских интерфейсов с помощью Tkinter. В нём объясняются ключевые концепции и на примерах показаны рекомендуемые подходы с использованием современного API.
-
- Справочник по Tkinter 8.5: графический интерфейс для Python
-
Справочная документация по Tkinter 8.5 с описанием доступных классов, методов и параметров.
Ресурсы по Tcl/Tk:
-
- Команды Tk
-
Подробный справочник по каждой из команд Tcl/Tk, лежащих в основе Tkinter.
-
- Домашняя страница Tcl/Tk
-
Дополнительная документация и ссылки на разработку ядра Tcl/Tk.
Книги:
-
- Современный Tkinter для занятых разработчиков Python
-
Марк Роузман. (ISBN 978-1999149567)
-
- Создание графических интерфейсов на Python с помощью Tkinter
-
Алан Д. Мур. (ISBN 978-1788835886)
-
- Программирование на Python
-
Марк Лутц; книга содержит отличное описание Tkinter. (ISBN 978-0596158101)
-
- Tcl и набор инструментов Tk (2-е издание)
-
Джон Оустерхаут, создатель Tcl/Tk, и Кен Джонс; Tkinter в книге не рассматривается. (ISBN 978-0321336330)
Архитектура
Tcl/Tk — это не одна библиотека, а несколько отдельных модулей, каждый со своими функциями и официальной документацией. Бинарные выпуски Python также поставляются вместе с дополнительным модулем.
- Tcl
-
Tcl — это динамический интерпретируемый язык программирования, как и Python. Хотя его можно использовать самостоятельно как язык программирования общего назначения, чаще всего его встраивают в приложения на C в качестве скриптового движка или интерфейса к набору инструментов Tk. Библиотека Tcl предоставляет интерфейс на C для создания и управления одним или несколькими экземплярами интерпретатора Tcl, выполнения команд и скриптов Tcl в этих экземплярах и добавления пользовательских команд, реализованных на Tcl или C. У каждого интерпретатора есть очередь событий, а также средства для отправки событий в неё и их обработки. В отличие от Python, модель выполнения Tcl рассчитана на кооперативную многозадачность, и Tkinter служит мостом между этими моделями (подробности см. в разделе Модель потоков).
- Tk
-
Tk — это пакет Tcl, реализованный на C и добавляющий пользовательские команды для создания виджетов графического интерфейса и управления ими. Каждый объект
Tkсодержит собственный экземпляр интерпретатора Tcl с загруженным в него Tk. Виджеты Tk допускают широкую настройку, хотя и выглядят несколько устаревшими. Tk использует очередь событий Tcl для создания и обработки событий графического интерфейса. - Ttk
-
Тематический Tk (Ttk) — это более новое семейство виджетов Tk, которые выглядят гораздо лучше на разных платформах, чем многие классические виджеты Tk. Ttk распространяется в составе Tk начиная с версии 8.5. Привязки Python предоставляются отдельным модулем
tkinter.ttk.
Внутри Tk и Ttk используют средства базовой операционной системы: Xlib в Unix/X11, Cocoa в macOS и GDI в Windows.
Когда приложение Python использует класс Tkinter, например для создания виджета, модуль tkinter сначала формирует строку команды Tcl/Tk. Он передаёт эту строку внутреннему бинарному модулю _tkinter, который затем вызывает интерпретатор Tcl для её выполнения. После этого интерпретатор Tcl обращается к пакетам Tk и/или Ttk, которые, в свою очередь, вызывают Xlib, Cocoa или GDI.
Модули Tkinter
Поддержка Tkinter распределена между несколькими модулями. Большинству приложений понадобятся основной модуль tkinter, а также модуль tkinter.ttk, предоставляющий современный набор тематических виджетов и API:
from tkinter import * from tkinter import ttk
-
class tkinter.Tk(screenName=None, baseName=None, className='Tk', useTk=True, sync=False, use=None) -
Создаёт виджет верхнего уровня Tk, который обычно является главным окном приложения, и инициализирует интерпретатор Tcl для этого виджета. Каждый экземпляр связан с собственным интерпретатором Tcl.
Обычно класс
Tkсоздают, используя значения по умолчанию. Однако в настоящее время распознаются следующие именованные аргументы:- screenName
-
Если задано (в виде строки), устанавливает переменную окружения
DISPLAY. (Только X11) - baseName
-
Имя файла профиля. По умолчанию значение baseName определяется на основе имени программы (
sys.argv[0]). - className
-
Имя класса виджета. Используется в качестве имени файла профиля, а также имени, с которым вызывается Tcl (argv0 в interp).
- useTk
-
Если
True, инициализирует подсистему Tk. Функцияtkinter.Tcl()задаёт этому параметру значениеFalse. - sync
-
Если
True, выполняет все команды X-сервера синхронно, чтобы ошибки сообщались сразу. Можно использовать для отладки. (Только X11) - use
-
Задаёт id окна, в которое нужно встроить приложение, вместо создания отдельного окна верхнего уровня. id должен быть задан так же, как значение параметра -use для виджетов верхнего уровня (то есть иметь форму, подобную возвращаемой
winfo_id()).Обратите внимание: на некоторых платформах это будет работать правильно, только если id указывает на фрейм Tk или окно верхнего уровня с включённым параметром -container.
Tkсчитывает файлы профиля с именами.className.tclи.baseName.tcl, интерпретирует их содержимое в интерпретаторе Tcl и вызываетexec()для содержимого.className.pyи.baseName.py. Путь к файлам профиля задаётся переменной окруженияHOMEили, если она не определена, значениемos.curdir.-
tk -
Объект приложения Tk, созданный при создании экземпляра
Tk. Он предоставляет доступ к интерпретатору Tcl. У каждого виджета, связанного с одним и тем же экземпляромTk, атрибутtkимеет одинаковое значение.
-
master -
Объект виджета, содержащего этот виджет. Для
Tkзначение master равноNone, поскольку это главное окно. Термины master и parent близки по значению и иногда используются как взаимозаменяемые имена аргументов; однако вызовwinfo_parent()возвращает строку с именем виджета, аmasterвозвращает объект. Пары parent/child описывают древовидную связь, а master/slave — структуру контейнеров.
-
children -
Непосредственные потомки этого виджета в виде
dict, где ключами являются имена дочерних виджетов, а значениями — объекты их экземпляров.
-
tkinter.Tcl(screenName=None, baseName=None, className='Tk', useTk=False) -
Функция
Tcl()— это фабричная функция, создающая объект, похожий на объект классаTk, но без инициализации подсистемы Tk. Она особенно полезна, когда требуется управлять интерпретатором Tcl в среде, где не нужно создавать лишние окна верхнего уровня или где это невозможно (например, в системах Unix/Linux без X-сервера). Для объекта, созданного функциейTcl(), можно создать окно Toplevel (и инициализировать подсистему Tk), вызвав его методloadtk().
Модули, обеспечивающие поддержку Tk:
-
tkinter -
Основной модуль Tkinter.
-
tkinter.colorchooser -
Диалоговое окно, позволяющее пользователю выбрать цвет.
-
tkinter.commondialog -
Базовый класс для диалоговых окон, определённых в перечисленных здесь модулях.
-
tkinter.filedialog -
Стандартные диалоговые окна, позволяющие пользователю выбрать файл для открытия или сохранения.
-
tkinter.font -
Вспомогательные средства для работы со шрифтами.
-
tkinter.messagebox -
Доступ к стандартным диалоговым окнам Tk.
-
tkinter.scrolledtext -
Текстовый виджет со встроенной вертикальной полосой прокрутки.
-
tkinter.simpledialog -
Простые диалоговые окна и вспомогательные функции.
-
tkinter.ttk -
Набор тематических виджетов, появившийся в Tk 8.5 и предоставляющий современные аналоги многих классических виджетов основного модуля
tkinter.
Дополнительные модули:
-
_tkinter -
Бинарный модуль, содержащий низкоуровневый интерфейс к Tcl/Tk. Он автоматически импортируется основным модулем
tkinter, и разработчикам приложений не следует использовать его напрямую. Обычно это разделяемая библиотека (или DLL), но в некоторых случаях она может быть статически скомпонована с интерпретатором Python. -
idlelib -
Интегрированная среда разработки и обучения Python (IDLE). Основана на
tkinter. -
tkinter.constants -
Символьные константы, которые можно использовать вместо строк при передаче различных параметров вызовам Tkinter. Автоматически импортируются основным модулем
tkinter. -
tkinter.dnd -
(экспериментальный) Поддержка перетаскивания для
tkinter. Этот модуль будет объявлен устаревшим после замены на Tk DND. -
turtle -
Черепашья графика в окне Tk.
Краткое руководство по Tkinter
Этот раздел не предназначен для исчерпывающего изучения Tk или Tkinter. Для этого обратитесь к одному из упомянутых ранее внешних ресурсов. Вместо этого раздел даёт краткое представление о том, как выглядит приложение Tkinter, знакомит с основными концепциями Tk и объясняет устройство оболочки Tkinter.
Остальная часть раздела поможет определить, какие классы, методы и параметры понадобятся в приложении Tkinter, и где найти более подробную документацию по ним, в том числе в официальном справочнике Tcl/Tk.
Программа «Hello World»
Начнём с разбора приложения «Hello World» на Tkinter. Это не самая короткая из возможных программ, но в ней достаточно кода, чтобы показать несколько ключевых понятий, с которыми нужно познакомиться.
from tkinter import * from tkinter import ttk root = Tk() frm = ttk.Frame(root, padding=10) frm.grid() ttk.Label(frm, text="Hello World!").grid(column=0, row=0) ttk.Button(frm, text="Quit", command=root.destroy).grid(column=1, row=0) root.mainloop()
После импорта следующая строка создаёт экземпляр класса Tk, который инициализирует Tk и создаёт связанный с ним интерпретатор Tcl. Кроме того, создаётся окно верхнего уровня, называемое корневым окном, которое служит главным окном приложения.
В следующей строке создаётся виджет фрейма, который в данном случае будет содержать создаваемые далее метку и кнопку. Фрейм размещается внутри корневого окна.
Следующая строка создаёт виджет метки со статической текстовой строкой. Метод grid() используется для задания относительного расположения метки внутри содержащего её фрейма — это похоже на работу таблиц в HTML.
Затем создаётся виджет кнопки и размещается справа от метки. При нажатии она вызовет метод destroy() корневого окна.
Наконец, метод mainloop() отображает все элементы и обрабатывает ввод пользователя, пока программа не завершится.
Важные концепции Tk
Даже эта простая программа демонстрирует следующие ключевые концепции Tk:
- виджеты
-
Пользовательский интерфейс Tkinter состоит из отдельных виджетов. Каждый виджет представлен объектом Python, созданным из таких классов, как
ttk.Frame,ttk.Labelиttk.Button. - иерархия виджетов
-
Виджеты расположены в виде иерархии. Метка и кнопка находились внутри фрейма, который, в свою очередь, находился внутри корневого окна. При создании каждого дочернего виджета его родительский виджет передаётся первым аргументом конструктору виджета.
- параметры конфигурации
-
У виджетов есть параметры конфигурации, изменяющие их внешний вид и поведение, например текст, отображаемый в метке или на кнопке. У разных классов виджетов разные наборы параметров.
- управление геометрией
-
Созданные виджеты не добавляются в пользовательский интерфейс автоматически. За их размещение в интерфейсе отвечает менеджер геометрии, например
grid. - цикл обработки событий
-
Tkinter реагирует на ввод пользователя, изменения в программе и даже обновляет экран, только когда активно выполняется цикл обработки событий. Если программа не выполняет этот цикл, пользовательский интерфейс не будет обновляться.
Как Tkinter взаимодействует с Tcl/Tk
Когда приложение использует классы и методы Tkinter, тот внутри формирует строки с командами Tcl/Tk и выполняет эти команды в интерпретаторе Tcl, связанном с экземпляром Tk вашего приложения.
Понимание того, как выглядят эти базовые команды Tcl/Tk, бывает полезно при работе со справочной документацией, поиске нужного метода или параметра, адаптации существующего кода или отладке приложения Tkinter.
Для наглядности ниже приведён эквивалент на Tcl/Tk основной части приведённого выше скрипта Tkinter.
ttk::frame .frm -padding 10 grid .frm grid [ttk::label .frm.lbl -text "Hello World!"] -column 0 -row 0 grid [ttk::button .frm.btn -text "Quit" -command "destroy ."] -column 1 -row 0
Синтаксис Tcl похож на синтаксис многих командных оболочек: первое слово — это выполняемая команда, за которой следуют её аргументы, разделённые пробелами. Не углубляясь в подробности, обратите внимание на следующее:
- Команды создания виджетов (например,
ttk::frame) соответствуют классам виджетов в Tkinter. - Параметры виджетов Tcl (например,
-text) соответствуют именованным аргументам в Tkinter. - В Tcl на виджеты ссылаются с помощью пути (например,
.frm.btn), тогда как Tkinter использует не имена, а ссылки на объекты. - Положение виджета в иерархии кодируется в его (иерархическом) пути, где в качестве разделителя используется
.(точка). Путь корневого окна — просто.(точка). В Tkinter иерархия задаётся не путями, а указанием родительского виджета при создании каждого дочернего виджета. - Операции, реализованные в Tcl как отдельные команды (например,
gridилиdestroy), представлены в Tkinter как методы объектов-виджетов. Вскоре вы увидите, что в других случаях Tcl использует конструкции, похожие на вызовы методов объектов-виджетов и более близкие к тому, что применяется в Tkinter.
Как это сделать? Что делает этот параметр?
Если вы не знаете, как выполнить что-либо в Tkinter, и не можете сразу найти нужную информацию в используемом руководстве или справочнике, вам могут помочь несколько приёмов.
Прежде всего помните, что работа отдельных виджетов может различаться в разных версиях Tkinter и Tcl/Tk. Если вы ищете документацию, убедитесь, что она относится к версиям Python и Tcl/Tk, установленным в вашей системе.
При поиске сведений об использовании API полезно знать точное имя используемого класса, параметра или метода. Интроспекция — в интерактивной оболочке Python или с помощью print() — поможет определить нужные элементы.
Чтобы узнать доступные параметры конфигурации любого виджета, вызовите его метод configure(). Он возвращает словарь с различными сведениями о каждом объекте, включая значения по умолчанию и текущие значения. Чтобы получить только имена параметров, используйте keys().
btn = ttk.Button(frm, ...) print(btn.configure().keys())
Поскольку у многих виджетов есть общие параметры конфигурации, полезно выяснить, какие из них относятся только к определённому классу виджета. Один из способов — сравнить список параметров со списком для более простого виджета, например фрейма.
print(set(btn.configure().keys()) - set(frm.configure().keys()))
Аналогичным образом список доступных методов объекта-виджета можно получить с помощью стандартной функции dir(). Если попробовать это сделать, окажется, что существует более 200 общих методов виджетов; поэтому полезно определить, какие методы относятся только к конкретному классу виджета.
print(dir(btn)) print(set(dir(btn)) - set(dir(frm)))
Модель потоков
Python и Tcl/Tk используют совершенно разные модели потоков, которые tkinter пытается объединить. Если вы используете потоки, вам может быть полезно знать об этом.
С интерпретатором Python может быть связано много потоков. В Tcl можно создавать несколько потоков, но с каждым потоком связан отдельный экземпляр интерпретатора Tcl. Потоки также могут создавать несколько экземпляров интерпретатора, однако каждый экземпляр может использоваться только потоком, который его создал.
Каждый объект Tk, созданный с помощью tkinter, содержит интерпретатор Tcl. Он также отслеживает, какой поток создал этот интерпретатор. Вызовы tkinter можно выполнять из любого потока Python. Внутри, если вызов поступает из потока, отличного от того, который создал объект Tk, событие помещается в очередь событий интерпретатора, а после выполнения результат возвращается вызвавшему потоку Python.
Приложения Tcl/Tk обычно управляются событиями: после инициализации интерпретатор запускает цикл обработки событий (то есть Tk.mainloop()) и обрабатывает события. Поскольку он однопоточный, обработчики событий должны выполняться быстро, иначе они будут препятствовать обработке других событий. Чтобы этого избежать, длительные вычисления не следует выполнять в обработчике событий: их нужно либо разбивать на небольшие части с помощью таймеров, либо выполнять в другом потоке. Это отличается от многих наборов инструментов для графического интерфейса, где графический интерфейс работает в отдельном потоке, полностью отделённом от кода приложения, включая обработчики событий.
Если интерпретатор Tcl не выполняет цикл обработки событий и не обрабатывает события, любые вызовы tkinter из потоков, отличных от потока, в котором работает интерпретатор Tcl, завершатся ошибкой.
Существует несколько особых случаев:
- Библиотеки Tcl/Tk могут быть собраны без поддержки потоков. В этом случае вызовы
tkinterобращаются к библиотеке из исходного потока Python, даже если он отличается от потока, создавшего интерпретатор Tcl. Глобальная блокировка гарантирует, что одновременно выполняется только один вызов. - Хотя
tkinterпозволяет создавать несколько экземпляров объектаTk(с собственными интерпретаторами), все интерпретаторы, принадлежащие одному потоку, используют общую очередь событий, что быстро приводит к проблемам. На практике не создавайте более одного экземпляраTkодновременно. В противном случае лучше создавать их в отдельных потоках и убедиться, что используется сборка Tcl/Tk с поддержкой потоков. - Блокирующие обработчики событий — не единственный способ помешать интерпретатору Tcl вернуться в цикл обработки событий. Можно даже запустить несколько вложенных циклов обработки событий или полностью отказаться от цикла обработки событий. Если вы используете нестандартные механизмы обработки событий или потоков, помните об этих возможностях.
- Некоторые отдельные функции
tkinterв настоящее время работают только при вызове из потока, создавшего интерпретатор Tcl.
Краткий справочник
Настройка параметров
Параметры управляют такими характеристиками виджета, как цвет и ширина границы. Параметры можно задавать тремя способами:
- При создании объекта с помощью именованных аргументов
-
fred = Button(self, fg="red", bg="blue")
- После создания объекта, обращаясь к имени параметра как к индексу словаря
-
fred["fg"] = "red" fred["bg"] = "blue"
- С помощью метода config() для обновления нескольких атрибутов после создания объекта
-
fred.config(fg="red", bg="blue")
Полное описание параметра и его поведения см. на справочных страницах Tk для соответствующего виджета.
Обратите внимание, что на справочных страницах для каждого виджета перечислены «СТАНДАРТНЫЕ ПАРАМЕТРЫ» и «ПАРАМЕТРЫ, СПЕЦИФИЧНЫЕ ДЛЯ ВИДЖЕТА». Первые — это параметры, общие для многих виджетов, вторые — параметры, характерные именно для данного виджета. Стандартные параметры описаны на справочной странице options(3).
В этом документе стандартные параметры не отделяются от параметров, специфичных для виджета. Некоторые параметры не применимы к отдельным типам виджетов. Наличие у виджета определённого параметра зависит от его класса: у кнопок есть параметр command, у меток — нет.
Поддерживаемые виджетом параметры перечислены на его справочной странице; также их можно запросить во время выполнения, вызвав метод config() без аргументов или метод keys() для этого виджета. Эти вызовы возвращают словарь, ключами которого являются имена параметров в виде строк (например, 'relief'), а значениями — кортежи из 5 элементов.
Некоторые параметры, например bg, являются сокращёнными вариантами распространённых параметров с длинными именами (bg — сокращение для «background»). Если передать методу config() имя сокращённого параметра, он вернёт кортеж из 2 элементов, а не из 5. Возвращённый кортеж из 2 элементов содержит имя синонима и «настоящий» параметр (например, ('bg', 'background')).
Индекс | Значение | Пример |
|---|---|---|
0 | имя параметра |
|
1 | имя параметра для поиска в базе данных |
|
2 | класс параметра для поиска в базе данных |
|
3 | значение по умолчанию |
|
4 | текущее значение |
|
Пример:
>>> print(fred.config())
{'relief': ('relief', 'relief', 'Relief', 'raised', 'groove')}
Разумеется, в напечатанный словарь войдут все доступные параметры и их значения. Здесь приведён лишь пример.
Упаковщик
Упаковщик — один из механизмов управления геометрией в Tk. Менеджеры геометрии используются для задания взаимного расположения виджетов внутри их контейнера — общего родительского виджета. В отличие от более громоздкого размещения (которое используется реже и здесь не рассматривается), упаковщик принимает качественное описание взаимного расположения — сверху, слева от, заполняя и т. п. — и сам вычисляет точные координаты размещения.
Размер любого родительского виджета определяется размером находящихся внутри него «подчинённых виджетов». Упаковщик управляет тем, где подчинённые виджеты располагаются внутри родительского виджета, в который они упакованы. Чтобы получить нужную компоновку, можно упаковывать виджеты во фреймы, а фреймы — в другие фреймы. Кроме того, после упаковки расположение динамически корректируется при изменении конфигурации.
Обратите внимание: виджеты не отображаются, пока для них не задана геометрия с помощью менеджера геометрии. Частая ошибка новичков — забыть задать геометрию, а затем удивляться, почему виджет создан, но не отображается. Виджет появится только после того, как к нему будет применён, например, метод pack() упаковщика.
Метод pack() можно вызывать с парами «именованный параметр/значение», которые управляют расположением виджета внутри контейнера и его поведением при изменении размера главного окна приложения. Вот несколько примеров:
fred.pack() # defaults to side = "top" fred.pack(side="left") fred.pack(expand=1)
Параметры упаковщика
Подробные сведения об упаковщике и принимаемых им параметрах см. на справочных страницах и на странице 183 книги Джона Аустерхоута.
- anchor
-
Тип привязки. Определяет, где упаковщик размещает каждый подчинённый виджет в выделенной ему области.
- expand
-
Логическое значение:
0или1. - fill
-
Допустимые значения:
'x','y','both','none'. - ipadx и ipady
-
Расстояние, задающее внутренний отступ с каждой стороны подчинённого виджета.
- padx и pady
-
Расстояние, задающее внешний отступ с каждой стороны подчинённого виджета.
- side
-
Допустимые значения:
'left','right','top','bottom'.
Связь переменных с виджетами
Текущее значение некоторых виджетов (например, виджетов ввода текста) можно напрямую связать с переменными приложения с помощью специальных параметров. Это параметры variable, textvariable, onvalue, offvalue и value. Связь работает в обоих направлениях: если переменная изменится по какой-либо причине, связанный с ней виджет обновится, чтобы отобразить новое значение.
К сожалению, в текущей реализации tkinter нельзя передать виджету произвольную переменную Python через параметр variable или textvariable. Это работает только с переменными, являющимися подклассами класса Variable, определённого в tkinter.
Уже определено несколько полезных подклассов Variable: StringVar, IntVar, DoubleVar и BooleanVar. Чтобы прочитать текущее значение такой переменной, вызовите её метод get(), а чтобы изменить значение — метод set(). Если следовать этому соглашению, виджет будет всегда отслеживать значение переменной без дополнительных действий с вашей стороны.
Например:
import tkinter as tk
class App(tk.Frame):
def __init__(self, master):
super().__init__(master)
self.pack()
self.entrythingy = tk.Entry()
self.entrythingy.pack()
# Create the application variable.
self.contents = tk.StringVar()
# Set it to some value.
self.contents.set("this is a variable")
# Tell the entry widget to watch this variable.
self.entrythingy["textvariable"] = self.contents
# Define a callback for when the user hits return.
# It prints the current value of the variable.
self.entrythingy.bind('<Key-Return>',
self.print_contents)
def print_contents(self, event):
print("Hi. The current entry content is:",
self.contents.get())
root = tk.Tk()
myapp = App(root)
myapp.mainloop()
Менеджер окон
В Tk есть служебная команда wm для взаимодействия с менеджером окон. Параметры команды wm позволяют управлять такими характеристиками, как заголовки, расположение, растровые изображения значков и т. п. В tkinter эти команды реализованы как методы класса Wm. Виджеты верхнего уровня являются подклассами класса Wm, поэтому могут напрямую вызывать методы Wm.
Чтобы получить окно верхнего уровня, содержащее заданный виджет, часто достаточно обратиться к его родительскому виджету. Разумеется, если виджет упакован во фрейм, его родительский виджет не будет окном верхнего уровня. Чтобы получить окно верхнего уровня, содержащее произвольный виджет, можно вызвать метод _root(). Имя этого метода начинается с подчёркивания, указывая на то, что функция является частью реализации, а не интерфейсом к функциональности Tk.
Вот несколько типичных примеров использования:
import tkinter as tk
class App(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.pack()
# create the application
myapp = App()
#
# here are method calls to the window manager class
#
myapp.master.title("My Do-Nothing Application")
myapp.master.maxsize(1000, 400)
# start the program
myapp.mainloop()
Типы данных параметров Tk
- anchor
-
Допустимые значения — стороны света:
"n","ne","e","se","s","sw","w","nw", а также"center". - bitmap
-
Есть восемь встроенных растровых изображений с именами:
'error','gray25','gray50','hourglass','info','questhead','question','warning'. Чтобы указать имя файла растрового изображения X, задайте полный путь к файлу с префиксом@, как в"@/usr/contrib/bitmap/gumby.bit". - boolean
-
Можно передать целое число 0 или 1 либо строку
"yes"или"no". - callback
-
Это любая функция Python, не принимающая аргументов. Например:
def print_it(): print("hi there") fred["command"] = print_it - color
-
Цвета можно задавать именами цветов X из файла rgb.txt или строками, представляющими значения RGB в диапазоне 4 бит:
"#RGB", 8 бит:"#RRGGBB", 12 бит:"#RRRGGGBBB"или 16 бит:"#RRRRGGGGBBBB", где R, G и B могут быть любыми допустимыми шестнадцатеричными цифрами. Подробности см. на странице 160 книги Аустерхоута. - cursor
-
Можно использовать стандартные имена курсоров X из
cursorfont.hбез префиксаXC_. Например, чтобы получить курсор в виде руки (XC_hand2), используйте строку"hand2". Также можно указать собственные файлы растрового изображения и маски. См. страницу 179 книги Аустерхоута. - distance
-
Расстояния на экране можно задавать в пикселях или в абсолютных единицах. Пиксели задаются числами, а абсолютные расстояния — строками, в которых завершающий символ обозначает единицу измерения:
cдля сантиметров,iдля дюймов,mдля миллиметров,pдля типографских пунктов. Например, 3,5 дюйма записываются как"3.5i". - font
-
Tk использует формат имени шрифта в виде списка, например
{courier 10 bold}. Положительные размеры шрифта измеряются в пунктах, отрицательные — в пикселях. - geometry
-
Это строка вида
widthxheight, где ширина и высота для большинства виджетов измеряются в пикселях (а для виджетов, отображающих текст, — в символах). Например:fred["geometry"] = "200x100". - justify
-
Допустимые значения: строки
"left","center","right"и"fill". - region
-
Это строка из четырёх элементов, разделённых пробелами; каждый элемент представляет собой допустимое расстояние (см. выше). Например, допустимыми областями являются
"2 3 4 5","3i 2i 4.5i 2i"и"3c 2c 4c 10.43c". - relief
-
Определяет стиль границы виджета. Допустимые значения:
"raised","sunken","flat","groove"и"ridge". - scrollcommand
-
Почти всегда это метод
set()некоторого виджета полосы прокрутки, однако можно использовать любой метод виджета, принимающий один аргумент. - wrap
-
Допустимые значения:
"none","char"или"word".
Привязки и события
Метод bind команды виджета позволяет отслеживать определённые события и вызывать функцию обратного вызова при возникновении события заданного типа. Метод bind имеет следующий вид:
def bind(self, sequence, func, add=''):
где:
- sequence
-
— строка, задающая тип целевого события. (Подробности см. на справочной странице bind(3tk) и на странице 201 книги Джона Аустерхоута
Tcl and the Tk Toolkit (2nd edition).) - func
-
— функция Python, принимающая один аргумент и вызываемая при возникновении события. В качестве аргумента ей передаётся экземпляр Event. (Функции, используемые таким образом, обычно называются функциями обратного вызова.)
- add
-
— необязательный параметр:
''или'+'. Пустая строка указывает, что эта привязка должна заменить все остальные привязки, связанные с данным событием. Значение'+'означает, что функцию нужно добавить в список функций, привязанных к этому типу события.
Например:
def turn_red(self, event):
event.widget["activeforeground"] = "red"
self.button.bind("<Enter>", self.turn_red)
Обратите внимание, как в функции обратного вызова turn_red() используется поле widget события. Это поле содержит виджет, получивший событие X. В следующей таблице перечислены другие доступные поля события и их обозначения в Tk, которые могут пригодиться при обращении к справочным страницам Tk.
Tk | Поле события Tkinter | Tk | Поле события Tkinter |
|---|---|---|---|
%f | focus | %A | char |
%h | height | %E | send_event |
%k | keycode | %K | keysym |
%s | state | %N | keysym_num |
%t | time | %T | type |
%w | width | %W | widget |
%x | x | %X | x_root |
%y | y | %Y | y_root |
Параметр index
Для ряда виджетов требуется передавать параметры «индекс». Они используются для указания конкретного места в виджете Text, определённых символов в виджете Entry или конкретных пунктов меню в виджете Menu.
- Индексы виджета Entry (index, view index и т. д.)
-
У виджетов Entry есть параметры, указывающие на позиции символов в отображаемом тексте. Для обращения к этим специальным позициям в текстовых виджетах можно использовать следующие функции
tkinter: - Индексы виджета Text
-
Система обозначений индексов для виджетов Text очень богата; лучше всего она описана на справочных страницах Tk.
- Индексы меню (menu.invoke(), menu.entryconfig() и т. д.)
-
Некоторые параметры и методы меню управляют определёнными его пунктами. Когда для параметра или аргумента требуется индекс меню, можно передать:
- целое число, обозначающее порядковую позицию пункта в виджете, начиная сверху с 0;
- строку
"active", обозначающую пункт меню, на который в данный момент наведён курсор; - строку
"last", обозначающую последний пункт меню; - целое число с префиксом
@, например@6; в этом случае целое число интерпретируется как координата y в пикселях в системе координат меню; - строку
"none", обозначающую отсутствие пункта меню; чаще всего её используют с menu.activate() для деактивации всех пунктов; наконец, - текстовую строку, сопоставляемую с метками пунктов меню по шаблону при просмотре меню сверху вниз. Обратите внимание: этот тип индекса проверяется после всех остальных, поэтому совпадения с пунктами меню, помеченными как
last,activeилиnone, могут быть интерпретированы как указанные выше литералы.
Изображения
Изображения разных форматов можно создавать с помощью соответствующего подкласса tkinter.Image:
-
BitmapImageдля изображений в формате XBM. -
PhotoImageдля изображений в форматах PGM, PPM, GIF и PNG. Последний формат поддерживается начиная с Tk 8.6.
Изображения обоих типов создаются с помощью параметра file или data (доступны и другие параметры).
Изменено в версии 3.13: Добавлен метод PhotoImage copy_replace() для копирования области одного изображения в другое, в том числе с увеличением и/или субдискретизацией пикселей. В методы PhotoImage copy(), zoom() и subsample() добавлен параметр from_coords. В метод PhotoImage copy() добавлены параметры zoom и subsample.
Затем объект изображения можно использовать везде, где какой-либо виджет поддерживает параметр image (например, в метках, кнопках и меню). В этих случаях Tk не сохраняет ссылку на изображение. Когда удаляется последняя ссылка Python на объект изображения, данные изображения тоже удаляются, и Tk отображает пустую область там, где использовалось изображение.
См. также
Пакет Pillow добавляет поддержку таких форматов, как BMP, JPEG, TIFF и WebP, а также других.
Обработчики файлов
Tk позволяет зарегистрировать и отменить регистрацию функции обратного вызова, которая будет вызываться главным циклом Tk, когда для файлового дескриптора становится возможен ввод-вывод. Для каждого файлового дескриптора можно зарегистрировать только один обработчик. Пример кода:
import tkinter widget = tkinter.Tk() mask = tkinter.READABLE | tkinter.WRITABLE widget.tk.createfilehandler(file, mask, callback) ... widget.tk.deletefilehandler(file)
Эта возможность недоступна в Windows.
Поскольку неизвестно, сколько байтов доступно для чтения, не следует использовать методы BufferedIOBase или TextIOBase read() или readline(), поскольку они будут пытаться прочитать заранее заданное количество байтов. Для сокетов подойдут методы recv() или recvfrom(); для других файлов используйте чтение без буферизации или os.read(file.fileno(), maxbytecount).
-
Widget.tk.createfilehandler(file, mask, func) -
Регистрирует функцию обратного вызова обработчика файла func. Аргумент file может быть объектом с методом
fileno()(например, объектом файла или сокета) либо целочисленным файловым дескриптором. Аргумент mask представляет собой комбинацию побитового ИЛИ любых трёх приведённых ниже констант. Функция обратного вызова вызывается следующим образом:callback(file, mask)
-
Widget.tk.deletefilehandler(file) -
Отменяет регистрацию обработчика файла.
-
_tkinter.READABLE -
_tkinter.WRITABLE -
_tkinter.EXCEPTION -
Константы, используемые в аргументах mask.
© 2001–2025 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/tkinter.html