Spec-Zone.ru › Python 3.11

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.

Книги:

  • Modern Tkinter for Busy Python Developers

    Марк Роземан. (ISBN 978-1999149567)

  • Python GUI программирование с Tkinter

    Алан Д. Мур. (ISBN 978-1788835886)

  • Programming Python

    Марк Лутц; имеет отличное описание Tkinter. (ISBN 978-0596158101)

  • Tcl и Tk Toolkit (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, начиная с версии Tk 8.5. Python-связки предоставляются в отдельном модуле tkinter.ttk.

Внутренне Tk и Ttk используют средства базовой операционной системы, т. е. Xlib на Unix/X11, Cocoa на macOS, GDI на Windows.

Когда ваше приложение Python использует класс в Tkinter, например, для создания виджета, модуль tkinter сначала собирает строку Tcl/Tk-команды. Затем он передаёт эту строку Tcl-команды внутреннему двоичному модулю _tkinter, который затем вызывает интерпретатор Tcl для её оценки. Интерпретатор Tcl затем вызовет пакеты Tk и/или Ttk, которые в свою очередь сделают вызовы Xlib, Cocoa или GDI.

END_OF_DOCUMENT_MARKER

Модули 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.

tkinter.tix

(устарело) Более старая сторонняя программа Tcl/Tk, добавляющая несколько новых виджетов. Лучшие альтернативы для большинства можно найти в tkinter.ttk.

turtle

Графика черепахи в окне Tk.

Tkinter Life Preserver

Этот раздел не предназначен для того, чтобы быть исчерпывающим руководством по 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, внутри Tkinter собираются строки, представляющие команды Tcl/Tk, и эти команды выполняются в интерпретаторе Tcl, присоединенном к экземпляру вашего приложения Tk.

Независимо от того, пытаетесь ли вы просмотреть справочную документацию, найти нужный метод или параметр, адаптировать какой-либо существующий код или отладить ваше приложение Tkinter, бывают моменты, когда полезно понять, как выглядят эти базовые команды Tcl/Tk.

Чтобы проиллюстрировать, вот эквивалент 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()) и реагирует на события. Поскольку он однопоточный, обработчики событий должны реагировать быстро, иначе они заблокируют обработку других событий. Чтобы избежать этого, любые длительные вычисления не должны выполняться в обработчике событий, а либо разбиваются на более мелкие части с использованием таймеров, либо выполняются в другом потоке. Это отличается от многих GUI-библиотек, где GUI выполняется в полностью отдельном потоке от всего кода приложения, включая обработчики событий.

Если интерпретатор 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. Виджеты Toplevel наследуются от класса Wm и поэтому могут напрямую вызывать методы Wm.

Чтобы получить окно toplevel, содержащее определённый виджет, вы часто можете просто обратиться к мастеру виджета. Конечно, если виджет был упакован внутри фрейма, мастер не будет представлять окно toplevel. Чтобы получить окно toplevel, содержащее произвольный виджет, вы можете вызвать метод _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, принимающая один аргумент, которая будет вызвана при возникновении события. В качестве аргумента будет передано событие (функции, используемые таким образом, обычно называют функциями обратного вызова).

add

необязательный параметр, либо '' , либо '+'. Передача пустой строки означает, что это связывание должно заменить любые другие связывания, связанные с этим событием. Передача '+' означает, что эта функция должна быть добавлена в список функций, связанных с этим типом событий.

Например:

def turn_red(self, event):
    event.widget["activeforeground"] = "red"

self.button.bind("<Enter>", self.turn_red)

Обратите внимание, как в функции обратного вызова turn_red() обращается к полю виджета события. Это поле содержит виджет, который поймал событие 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

Несколько виджетов требуют параметров «index» для передачи. Они используются для указания определённого места в виджете Text, конкретных символов в виджете Entry или конкретных пунктов меню в виджете Menu.

Индексы виджетов Entry (индекс, индекс отображения и т. д.)

Виджеты 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 (другие параметры также доступны).

Объект изображения затем может быть использован там, где поддерживается параметр image некоторым виджетом (например, метками, кнопками, меню). В этих случаях Tk не будет сохранять ссылку на изображение. При удалении последней ссылки Python на объект изображения данные изображения также удаляются, и Tk отобразит пустую область там, где использовалось изображение.

См. также

Пакет Pillow добавляет поддержку форматов, таких как BMP, JPEG, TIFF и WebP, среди прочих.

Обработчики файлов

Tk позволяет регистрировать и отменять регистрацию функции обратного вызова, которая будет вызываться из цикла Tk mainloop, когда доступен ввод-вывод для дескриптора файла. Для каждого дескриптора файла может быть зарегистрирован только один обработчик. Пример кода:

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–2023 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.11/library/tkinter.html

Spec-Zone.ru

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