Spec-Zone.ru › Python 3.13

tkinter — Python-интерфейс к Tcl/Tk

Исходный код: Lib/tkinter/__init__.py

Пакет tkinter («Tk-интерфейс») — стандартный Python-интерфейс к набору инструментов Tcl/Tk для графических пользовательских интерфейсов. Tk и tkinter доступны на большинстве Unix-платформ, включая macOS, а также на системах Windows.

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

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

Tkinter — не просто тонкий обертка, но добавляет значительный объём собственной логики, чтобы опыт работы стал более питоновским. Данная документация будет сосредоточена на этих добавках и изменениях, а для деталей, которые не были изменены, обратитесь к официальной документации Tcl/Tk.

Примечание

Tcl/Tk 8.5 (2007) представил современный набор тематических компонентов пользовательского интерфейса вместе с новым API для их использования. Доступны как старые, так и новые API. Большинство документации, которую вы найдёте в интернете, всё ещё использует старый API и может быть сильно устаревшей.

См. также

  • TkDocs

    Обширное руководство по созданию пользовательских интерфейсов с Tkinter. Объясняет ключевые понятия и иллюстрирует рекомендуемые подходы, используя современный API.

  • Tkinter 8.5 справочник: GUI для Python

    Справочная документация по Tkinter 8.5, подробно описывающая доступные классы, методы и параметры.

Ресурсы Tcl/Tk:

  • Команды Tk

    Полный справочник по каждой из основных команд Tcl/Tk, используемых Tkinter.

  • Главная страница Tcl/Tk

    Дополнительная документация и ссылки на разработку ядра Tcl/Tk.

Книги:

  • Современный Tkinter для занятых разработчиков Python

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

  • Разработка графических интерфейсов с Tkinter на Python

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

  • Программирование на Python

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

  • Tcl и набор инструментов Tk (2-е издание)

    Джон Оустерхаут, изобретатель Tcl/Tk, и Кен Джонс; не охватывает Tkinter. (ISBN 978-0321336330)

Архитектура

Tcl/Tk — не единая библиотека, а состоит из нескольких отдельных модулей, каждый со своей функциональностью и собственной официальной документацией. Бинарные сборки Python также поставляют с собой дополнительный модуль.

Tcl

Tcl — динамический интерпретируемый язык программирования, как и Python. Хотя его можно использовать как самостоятельный язык программирования общего назначения, он чаще всего встраивается в C-приложения в качестве скриптового движка или интерфейса к набору инструментов Tk. Библиотека Tcl имеет C-интерфейс для создания и управления одним или несколькими экземплярами Tcl-интерпретатора, выполнения Tcl-команд и скриптов в этих экземплярах, а также добавления пользовательских команд, реализованных на Tcl или C. Каждый интерпретатор имеет очередь событий, и существуют средства для отправки событий в него и их обработки. В отличие от Python, модель выполнения Tcl разработана для кооперативного многозадачного выполнения, и Tkinter устраняет это различие (см. Модель потоков для получения подробностей).

Tk

Tk — Tcl-пакет, реализованный на C, который добавляет пользовательские команды для создания и управления виджетами 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.

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

Виджет Text со встроенной вертикальной полосой прокрутки.

tkinter.simpledialog

Базовые диалоговые окна и удобные функции.

tkinter.ttk

Набор тематических виджетов, представленный в Tk 8.5, предоставляющий современные альтернативы многим классическим виджетам в основном модуле tkinter.

Дополнительные модули:

_tkinter

Бинарный модуль, содержащий низкоуровневый интерфейс к Tcl/Tk. Он автоматически импортируется основным модулем tkinter и никогда не должен использоваться программистами приложений напрямую. Обычно это общая библиотека (или DLL), но в некоторых случаях может быть статически связана с интерпретатором Python.

idlelib

Интегрированная среда разработки и обучения Python (IDLE). Основан на tkinter.

tkinter.constants

Символьные константы, которые можно использовать вместо строк при передаче различных параметров в вызовы Tkinter. Автоматически импортируется основным модулем tkinter.

tkinter.dnd

(экспериментально) Поддержка перетаскивания для tkinter. Это станет устаревшим, когда его заменит Tk DND.

turtle

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

Tkinter Life Preserver

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

Хотя все операции в 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).

Многие общие параметры и методы вы найдёте на страницах руководства по параметрам или 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 Bitmap укажите полный путь к файлу, предварив его @, как в "@/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

— строка, обозначающая целевой тип события. (См. страницу man 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, что может быть полезно при работе с страницами man 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 очень богата и лучше всего описывается в страницах man Tk.

Индексы меню (menu.invoke(), menu.entryconfig() и т. д.)

Некоторые параметры и методы для меню манипулируют конкретными пунктами меню. В любое время, когда требуется индекс меню для параметра или аргумента, можно передать:

  • целое число, которое ссылается на числовую позицию элемента в виджете, считая сверху, начиная с 0;
  • строку "active", которая относится к позиции меню, которая сейчас находится под курсором;
  • строку "last" которая относится к последнему пункту меню;
  • целое число, предваряемое @, как в @6, где целое число интерпретируется как координата y в пикселях в системе координат меню;
  • строку "none", которая обозначает отсутствие элемента меню, чаще всего используемая с menu.activate() для деактивации всех элементов, и наконец,
  • строку текста, которая сопоставляется по шаблону с меткой элемента меню, как сканируемая сверху вниз. Обратите внимание, что этот тип индекса рассматривается после всех остальных, что означает, что совпадения для элементов меню с метками last, active, или none могут быть интерпретированы как указанные выше литералы, вместо этого.

Изображения

Изображения различных форматов могут быть созданы с помощью соответствующего подкласса tkinter.Image:

  • BitmapImage для изображений в формате XBM.
  • PhotoImage для изображений в форматах PGM, PPM, GIF и PNG. Последний поддерживается, начиная с Tk 8.6.

Изображение любого типа создаётся с помощью параметра file или data (также доступны другие параметры).

Изменено в версии 3.13: Добавлен метод PhotoImage copy_replace() для копирования области из одного изображения в другое, возможно, с масштабированием и/или подвыборкой пикселей. Добавлен параметр from_coords к методам PhotoImage copy(), zoom() и subsample(). Добавлены параметры zoom и subsample к методу PhotoImage copy().

Объект изображения затем можно использовать там, где поддерживается параметр 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–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/tkinter.html

Spec-Zone.ru

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