Spec-Zone.ru › Python 3.13

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

Как пользоваться справочником Tcl/Tk

Как уже отмечалось, официальный справочник команд Tk (справочные страницы) часто содержит наиболее точное описание действий конкретных операций над виджетами. Даже если вы знаете нужное имя параметра или метода, информацию всё же может потребоваться искать в нескольких местах.

Хотя в Tkinter все операции реализованы как вызовы методов объектов-виджетов, вы уже видели, что многие операции Tcl/Tk представлены командами, которым первым параметром передаётся путь к виджету, а затем — необязательные параметры. Например:

destroy .
grid .frm.btn -column 0 -row 0

Другие операции, однако, больше похожи на методы, вызываемые для объекта-виджета (на самом деле при создании виджета в Tcl/Tk создаётся команда Tcl с именем пути виджета, первым параметром которой является имя вызываемого метода).

.frm.btn invoke
.frm.lbl configure -text "Goodbye"

В официальной справочной документации Tcl/Tk большинство операций, похожих на вызовы методов, описано на странице конкретного виджета (например, метод invoke() можно найти на справочной странице ttk::button), тогда как функции, которым виджет передаётся в качестве параметра, часто имеют собственную справочную страницу (например, grid).

Многие распространённые параметры и методы описаны на справочных страницах options или ttk::widget; остальные можно найти на странице конкретного класса виджетов.

У многих методов Tkinter составные имена, например winfo_x(), winfo_height(), winfo_viewable(). Документацию по всем этим методам можно найти на справочной странице winfo.

Примечание

Некоторые методы, имеющиеся у всех виджетов Tkinter, работают не с самим виджетом, а в глобальной области видимости, независимо от какого-либо виджета. Например, это методы для доступа к буферу обмена или системному звуковому сигналу. (Они реализованы как методы базового класса Widget, от которого наследуются все виджеты Tkinter.)

Модель потоков

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

имя параметра

'relief'

1

имя параметра для поиска в базе данных

'relief'

2

класс параметра для поиска в базе данных

'Relief'

3

значение по умолчанию

'raised'

4

текущее значение

'groove'

Пример:

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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API