Spec-Zone.ru › Python 3.10

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 не является тонким оболочкой, но добавляет значительное количество собственной логики, чтобы сделать опыт более pythonic. Данная документация сконцентрируется на этих добавках и изменениях, а для деталей, которые остались неизменными, будет использована официальная документация 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 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, который добавляет пользовательские команды для создания и управления виджетами GUI. Каждый объект 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.

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

Этот раздел не предназначен для проведения исчерпывающего туториала по Tk или Tkinter. Для этого обратитесь к одному из упомянутых ранее внешних ресурсов. Вместо этого этот раздел предоставляет очень краткий обзор того, как выглядит приложение Tkinter, определяет основополагающие понятия Tk и объясняет структуру обертки Tkinter.

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

Программа «Привет, мир»

Мы начнем с рассмотрения приложения «Привет, мир» в 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 (Tk commands) часто является наиболее точным описанием того, какие конкретные операции с виджетами выполняют. Даже зная имя опции или метода, который вам нужен, у вас все равно могут быть несколько мест для поиска.

Хотя все операции в 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, принимающей один аргумент, которая вызывается при появлении события. В качестве аргумента передается экземпляр 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

Ряд виджетов требуют передачи параметров «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, когда доступен ввод-вывод для дескриптора файла. Только один обработчик может быть зарегистрирован на один дескриптор файла. Пример кода:

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.10/library/tkinter.html

Spec-Zone.ru

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