Spec-Zone.ru › Python 3.12

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 — это не просто тонкий обертка, а добавляет немало собственной логики, чтобы опыт использования был более питоничным. Эта документация сосредоточится на этих добавках и изменениях и будет ссылаться на официальную документацию 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 programming with Tkinter

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

  • Programming Python

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

  • Tcl and the 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 для генерации и обработки событий GUI.

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.

Модули 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(), может иметь созданное окно верхнего уровня (и инициализированную подсистему 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 (со своим интерпретатором), все интерпретаторы, которые являются частью одного потока, используют общую очередь событий, что быстро становится неудобно. На практике не создавайте более одного экземпляра tkinter одновременно. В противном случае лучше создавать их в отдельных потоках и убедиться, что вы используете сборку 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. Этот возвращаемый кортеж будет содержать имя синонима и «настоящий» параметр (например, ('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.

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

Ряд виджетов требуют параметра «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 (есть и другие опции).

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

См. также

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

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

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

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

Spec-Zone.ru

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