# `tkinter` — Python interface to Tcl/Tk

Вихідний код: Lib/tkinter/__init__.py

The `tkinter` package («Tk interface») is the standard Python interface to the Tcl/Tk GUI toolkit. Both Tk and `tkinter` are available on most Unix platforms, including macOS, as well as on Windows systems.

Running `python -m tkinter` from the command line should open a window demonstrating a simple Tk interface, letting you know that `tkinter` is properly installed on your system, and also showing what version of Tcl/Tk is installed, so you can read the Tcl/Tk documentation specific to that version.

Tkinter підтримує низку версій Tcl/Tk, створених із підтримкою потоків або без неї. Офіційний двійковий випуск Python включає в себе Tcl/Tk 8.6. Перегляньте вихідний код для модуля `_tkinter`, щоб дізнатися більше про підтримувані версії.

Tkinter не є тонкою обгорткою, але додає достатню кількість власної логіки, щоб зробити досвід більш пітонічним. Ця документація зосереджуватиметься на цих доповненнях і змінах, а подробиці, які не змінилися, див. в офіційній документації Tcl/Tk.

Примітка

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

This is an optional module. If it is missing from your copy of CPython, look for documentation from your distributor (that is, whoever provided Python to you). If you are the distributor, see Requirements for optional modules.

Дивись також

- 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 GUI programming with Tkinter

    By Alan D. Moore. (ISBN 978-1788835886)

- Programming Python

    Марк Лутц; має чудове покриття Tkinter. (ISBN 978-0596158101)

- Tcl і Tk Toolkit (2-е видання)

    Джон Остерхаут, винахідник Tcl/Tk, і Кен Джонс; не охоплює Tkinter. (ISBN 978-0321336330)

## Архітектура

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

Tcl

  Tcl — це динамічна інтерпретована мова програмування, як і Python. Хоча його можна використовувати самостійно як мову програмування загального призначення, найчастіше його вбудовують у додатки C як механізм сценаріїв або інтерфейс до набору інструментів Tk. Бібліотека Tcl має інтерфейс C для створення та керування одним або декількома екземплярами інтерпретатора Tcl, запуску команд і сценаріїв Tcl у цих екземплярах і додавання спеціальних команд, реалізованих у Tcl або C. Кожен інтерпретатор має чергу подій, а також є засоби для надсилання до нього подій та їх обробки. На відміну від Python, модель виконання Tcl розроблена навколо кооперативної багатозадачності, і Tkinter усуває цю різницю (докладніше див. Модель потоків).

Тк

  Tk is a Tcl package implemented in C that adds custom commands to create and manipulate GUI widgets. Each `Tk` object embeds its own Tcl interpreter instance with Tk loaded into it. Tk’s widgets are very customizable, though at the cost of a dated appearance. Tk uses Tcl’s event queue to generate and process GUI events.

Ттк

  Тематичний Tk (Ttk) — це новіша сімейство віджетів Tk, які забезпечують набагато кращий вигляд на різних платформах, ніж багато класичних віджетів Tk. Ttk поширюється як частина Tk, починаючи з Tk версії 8.5. Прив’язки Python надаються в окремому модулі, `tkinter.ttk`.

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

When your Python application uses a class in Tkinter, e.g., to create a widget, the `tkinter` module first assembles a Tcl/Tk command string. It passes that Tcl command string to an internal `_tkinter` binary module, which then calls the Tcl interpreter to evaluate it. The Tcl interpreter will then call into the Tk and/or Ttk packages, which will in turn make calls to Xlib, Cocoa, or GDI.

## Модулі Tkinter

Support for Tkinter is spread across several modules. Most applications will need the main `tkinter` module, as well as the `tkinter.ttk` module, which provides the modern themed widget set and 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 походить від назви програми (`sys.argv[0]`).

  назва класу

    Назва класу віджетів. Використовується як файл профілю, а також як ім’я, з яким викликається Tcl (argv0 у interp).

  useTk

    Якщо `True`, ініціалізувати підсистему Tk. Функція `tkinter.Tcl()` встановлює значення `False`.

  синхронізація

    Якщо `True`, виконувати всі команди X-сервера синхронно, щоб повідомляти про помилки негайно. Можна використовувати для налагодження. (лише X11)

  використання

    Визначає id вікна, у яке потрібно вставити програму, замість того, щоб воно створювалося як незалежне вікно верхнього рівня. id потрібно вказати так само, як значення параметра -use для віджетів верхнього рівня (тобто воно має форму, подібну до тієї, яку повертає `winfo_id()`).

    Зауважте, що на деяких платформах це працюватиме належним чином, лише якщо id посилається на фрейм Tk або верхній рівень, для якого ввімкнено параметр -container.

  `Tk` reads and interprets profile files, named `.className.tcl` and `.baseName.tcl`, into the Tcl interpreter and calls `exec()` on the contents of `.className.py` and `.baseName.py`. The path for the profile files is the `HOME` environment variable or, if that isn’t defined, then `os.curdir`.

  tk

    Об’єкт програми Tk, створений шляхом створення екземпляра `Tk`. Це забезпечує доступ до інтерпретатора Tcl. Кожен віджет, до якого приєднано той самий екземпляр `Tk`, має однакове значення для свого атрибута `tk`.

  master

    The widget object that contains this widget. For `Tk`, the `master` is `None` because it is the main window. The terms master and parent are similar and sometimes used interchangeably as argument names; however, calling `winfo_parent()` returns a string of the widget name whereas `master` returns the object. parent/child reflects the tree-like relationship while master (or container)/content reflects the container structure.

  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`

  Themed widget set introduced in Tk 8.5, providing modern alternatives for many of the classic widgets in the main `tkinter` module.

Додаткові модулі:

`_tkinter`

  A binary module that contains the low-level interface to Tcl/Tk. It is automatically imported by the main `tkinter` module, and should never be used directly by application programmers. It is usually a shared library (or DLL), but might in some cases be statically linked with the Python interpreter.

`idlelib`

  Python’s Integrated Development and Learning Environment (IDLE). Based on `tkinter`.

`tkinter.constants`

  Symbolic constants that can be used in place of strings when passing various parameters to Tkinter calls. Automatically imported by the main `tkinter` module.

`tkinter.dnd`

  (experimental) Drag-and-drop support for `tkinter`. This will become deprecated when it is replaced with the Tk DND.

`turtle`

  Графіка Turtle у вікні Tk.

## Tkinter Life Preserver

Цей розділ не призначений для вичерпного підручника з Tk або Tkinter. Для цього зверніться до одного із зовнішніх ресурсів, згаданих раніше. Натомість цей розділ надає дуже швидку орієнтацію щодо того, як виглядає програма Tkinter, визначає основні концепції Tk і пояснює, як структурована оболонка Tkinter.

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

### Програма «Привіт, світ».

Ми почнемо з огляду програми «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

When your application uses Tkinter’s classes and methods, internally Tkinter is assembling strings representing Tcl/Tk commands, and executing those commands in the Tcl interpreter attached to your application’s `Tk` instance.

Незалежно від того, чи це спроба навігації по довідковій документації, спроба знайти правильний метод або параметр, адаптація деякого існуючого коду або налагодження вашої програми 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 ієрархія визначається не шляхом, а вказівкою батьківського віджета під час створення кожного дочірнього віджета.

- Operations which are implemented as separate commands in Tcl (like `grid` or `destroy`) are represented as methods on Tkinter widget objects. As you’ll see shortly, at other times Tcl uses what appear to be method calls on widget objects, which more closely mirror what is used in 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 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 and Tcl/Tk have very different threading models, which `tkinter` tries to bridge. If you use threads, you may need to be aware of this.

Інтерпретатор Python може мати багато потоків, пов’язаних із ним. У Tcl можна створити кілька потоків, але кожен потік має окремий екземпляр інтерпретатора Tcl, пов’язаний з ним. Потоки також можуть створювати більше одного екземпляра інтерпретатора, хоча кожен екземпляр інтерпретатора може використовуватися лише тим потоком, який його створив.

Each `Tk` object created by `tkinter` contains a Tcl interpreter. It also keeps track of which thread created that interpreter. Calls to `tkinter` can be made from any Python thread. Internally, if a call comes from a thread other than the one that created the `Tk` object, an event is posted to the interpreter’s event queue, and when executed, the result is returned to the calling Python thread.

Програми Tcl/Tk зазвичай керуються подіями, тобто після ініціалізації інтерпретатор запускає цикл подій (тобто `Tk.mainloop()`) і відповідає на події. Оскільки він однопотоковий, обробники подій повинні реагувати швидко, інакше вони заблокують обробку інших подій. Щоб уникнути цього, будь-які тривалі обчислення не повинні виконуватися в обробнику подій, а розбиваються на менші частини за допомогою таймерів або виконуються в іншому потоці. Це відрізняється від багатьох наборів інструментів графічного інтерфейсу, де графічний інтерфейс працює в повністю окремому потоці від усього коду програми, включаючи обробники подій.

If the Tcl interpreter is not running the event loop and processing events, any `tkinter` calls made from threads other than the one running the Tcl interpreter will fail.

Існує ряд особливих випадків:

- Tcl/Tk libraries can be built so they are not thread-aware. In this case, `tkinter` calls the library from the originating Python thread, even if this is different than the thread that created the Tcl interpreter. A global lock ensures only one call occurs at a time.

- While `tkinter` allows you to create more than one instance of a `Tk` object (with its own interpreter), all interpreters that are part of the same thread share a common event queue, which gets ugly fast. In practice, don’t create more than one instance of `Tk` at a time. Otherwise, it’s best to create them in separate threads and ensure you’re running a thread-aware Tcl/Tk build.

- Блокування обробників подій — не єдиний спосіб запобігти повторному входу інтерпретатора Tcl у цикл подій. Можна навіть запустити кілька вкладених циклів подій або повністю відмовитися від циклу подій. Якщо ви робите щось складне, коли йдеться про події чи ланцюжки, пам’ятайте про ці можливості.

- There are a few select `tkinter` functions that presently work only when called from the thread that created the Tcl interpreter.

## Зручний довідник

### Параметри налаштування

Параметри контролюють такі речі, як колір і ширина рамки віджета. Параметри можна встановити трьома способами:

Під час створення об’єкта, використовуючи ключові аргументи

      fred = Button(self, fg="red", bg="blue")

Після створення об’єкта назва параметра розглядається як індекс словника

      fred["fg"] = "red"
      fred["bg"] = "blue"

Використовуйте метод config() для оновлення кількох атрибутів після створення об’єкта

      fred.config(fg="red", bg="blue")

Щоб отримати повне пояснення даного параметра та його поведінки, перегляньте сторінки довідки Tk для відповідного віджета.

Зауважте, що на довідкових сторінках перераховано «СТАНДАРТНІ ПАРАМЕТРИ» та «СПЕЦИФІЧНІ ПАРАМЕТРИ ВІДЖЕТА» для кожного віджета. Перший — це список параметрів, які є спільними для багатьох віджетів, другий — параметри, які є ідіосинкратичними для цього конкретного віджета. Стандартні параметри задокументовані на сторінці довідки options(3).

У цьому документі не робиться різниці між стандартними параметрами та параметрами, що стосуються окремих віджетів. Деякі параметри не застосовуються до деяких типів віджетів. Чи відповідає даний віджет певній опції, залежить від класу віджета; кнопки мають параметр `команда`, а мітки — ні.

Параметри, які підтримує певний віджет, перераховані на сторінці довідки цього віджета, або їх можна запитати під час виконання, викликавши метод `config()` без аргументів або викликавши метод `keys()` у цьому віджеті. Поверненим значенням цих викликів є словник, ключем якого є ім’я опції у вигляді рядка (наприклад, `'relief'`), а значеннями є 5-ти кортежі.

Деякі параметри, як-от `bg`, є синонімами поширених параметрів із довгими назвами (`bg` є скороченням від «фон»). Передача методу `config()` імені скороченого параметра поверне 2-кортеж, а не 5-кортеж. 2-кортеж, переданий назад, міститиме назву синоніму та «справжній» параметр (наприклад, `('bg', 'background')`).

Індекс | Значення | приклад
--- | --- | ---
0 | назва опції | `''рельєф'`
1 | назва параметра для пошуку в базі даних | `''рельєф'`
2 | клас параметрів для пошуку в базі даних | `'Рельєф'`
3 | значення за замовчуванням | `'піднятий''`
4 | поточне значення | `'канавки'`

Приклад:

    >>> print(fred.config())
    {'relief': ('relief', 'relief', 'Relief', 'raised', 'groove')}

Звичайно, надрукований словник міститиме всі доступні варіанти та їхні значення. Це лише як приклад.

### Пакувальник

The packer is one of Tk’s geometry-management mechanisms. Geometry managers are used to specify the relative positioning of widgets within their container. In contrast to the more cumbersome placer (which is used less commonly, and we do not cover here), the packer takes qualitative relationship specification - above, to the left of, filling, etc - and works everything out to determine the exact placement coordinates for you.

The size of any container widget is determined by the size of the «content widgets» inside. The packer is used to control where content widgets appear inside the container into which they are packed. You can pack widgets into frames, and frames into other frames, in order to achieve the kind of layout you desire. Additionally, the arrangement is dynamically adjusted to accommodate incremental changes to the configuration, once it is packed.

Зауважте, що віджети не з’являться, доки їхню геометрію не буде визначено за допомогою менеджера геометрії. Поширеною ранньою помилкою є пропуск специфікації геометрії, а потім дивуватися, коли віджет створено, але нічого не з’явиться. Віджет з’явиться лише після того, як до нього буде застосовано, наприклад, метод пакувальника `pack()`.

Метод pack() можна викликати за допомогою пар ключове слово-параметр/значення, які визначають, де віджет має з’являтися в своєму контейнері та як він має поводитися, коли змінюється розмір головного вікна програми. Ось кілька прикладів:

    fred.pack()                     # defaults to side = "top"
    fred.pack(side="left")
    fred.pack(expand=1)

### Опції пакувальника

Щоб отримати докладнішу інформацію про пакувальник і параметри, які він може приймати, перегляньте сторінки довідки та сторінку 183 книги Джона Оустерхаута.

якір

  Anchor type. Denotes where the packer is to place each content in its parcel.

розширити

  Логічне значення, `0` або `1`.

заповнити

  Правильні значення: `'x'`, `'y'`, `'both'`, `'none'`.

ipadx і ipady

  A distance - designating internal padding on each side of the content.

padx і pady

  A distance - designating external padding on each side of the content.

бік

  Допустимі значення: `'left'`, `'right'`, `'top'`, `'bottom'`.

### З’єднання змінних віджетів

Налаштування поточного значення деяких віджетів (наприклад, віджетів для введення тексту) можна підключити безпосередньо до змінних програми за допомогою спеціальних параметрів. Ці параметри: `variable`, `textvariable`, `onvalue`, `offvalue` і `value`. Це підключення працює в обох напрямках: якщо змінна змінюється з будь-якої причини, віджет, до якого вона підключена, буде оновлено, щоб відобразити нове значення.

Unfortunately, in the current implementation of `tkinter` it is not possible to hand over an arbitrary Python variable to a widget through a `variable` or `textvariable` option. The only kinds of variables for which this works are variables that are subclassed from a class called Variable, defined in `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()

### Менеджер вікон

In Tk, there is a utility command, `wm`, for interacting with the window manager. Options to the `wm` command allow you to control things like titles, placement, icon bitmaps, and the like. In `tkinter`, these commands have been implemented as methods on the `Wm` class. Toplevel widgets are subclassed from the `Wm` class, and so can call the `Wm` methods directly.

To get at the toplevel window that contains a given widget, you can often just refer to the widget’s `master`. Of course if the widget has been packed inside of a frame, the `master` won’t represent a toplevel window. To get at the toplevel window that contains an arbitrary widget, you can call the `_root()` method. This method begins with an underscore to denote the fact that this function is part of the implementation, and not an interface to Tk functionality.

Ось кілька прикладів типового використання:

    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

якір

  Правовими значеннями є точки компаса: `"n"`, `"ne"`, `"e"`, `"se"`, `"s"`, `"sw"`, `"w"`, `"nw"`, а також `"center"`.

растрове зображення

  Є вісім вбудованих іменованих растрових зображень: `'error'`, `'gray25'`, `'gray50'`, `'hourglass'`, `'info'`, `'questhead'`, `'питання'`, `'попередження''`. Щоб вказати ім’я файлу растрового зображення X, укажіть повний шлях до файлу, перед яким стоїть `@`, як у `"@/usr/contrib/bitmap/gumby.bit"`.

логічний

  Ви можете передати цілі числа 0 або 1 або рядки `"yes"` чи `"no"`.

зворотній дзвінок

  Це будь-яка функція Python, яка не приймає аргументів. Наприклад:

      def print_it():
          print("hi there")
      fred["command"] = print_it

колір

  Кольори можна вказати як назви кольорів X у файлі rgb.txt або як рядки, що представляють значення RGB у 4 бітах: `"#RGB"`, 8 бітах: `"#RRGGBB"`, 12 бітах : `"#RRRGGGBBB"`, або 16 біт: `"#RRRRGGGBBBB"` діапазони, де R, G, B тут представляють будь-яку допустиму шістнадцяткову цифру. Подробиці дивіться на сторінці 160 книги Оустерхаута.

курсор

  Можна використовувати стандартні імена курсорів X із `cursorfont.h` без префікса `XC_`. Наприклад, щоб отримати курсор руки (`XC_hand2`), використовуйте рядок `"hand2"`. Ви також можете вказати власний растровий файл і файл маски. Дивіться сторінку 179 книги Оустерхаута.

відстань

  Відстань до екрана можна вказати як у пікселях, так і в абсолютних відстанях. Пікселі подаються у вигляді чисел, а абсолютні відстані – у вигляді рядків із кінцевим символом, що позначає одиниці: `c` для сантиметрів, `i` для дюймів, `m` для міліметрів, `p` для точок принтера . Наприклад, 3,5 дюйма виражається як `"3,5i"`.

шрифт

  Tk використовує формат назви шрифту списку, наприклад `{courier 10 bold}`. Розмір шрифту з додатними числами вимірюється в пунктах; розміри з від’ємними числами вимірюються в пікселях.

геометрія

  Це рядок у формі `ширинаxвисота`, де ширина та висота вимірюються в пікселях для більшості віджетів (у символах для віджетів, що відображають текст). Наприклад: `fred["geometry"] = "200x100"`.

виправдати

  Legal values are the strings: `"left"`, `"center"`, and `"right"`.

область

  Це рядок із чотирма розділеними пробілами елементами, кожен із яких є допустимою відстанню (див. вище). Наприклад: `"2 3 4 5"` і `"3i 2i 4.5i 2i"` і `"3c 2c 4c 10.43c"` є законними регіонами.

полегшення

  Визначає, яким буде стиль межі віджета. Допустимі значення: `"піднятий"`, `"заглиблений"`, `"плоский"`, `"канавка"` і `"гребінь"`.

команда прокручування

  Це майже завжди метод `set()` якогось віджета смуги прокрутки, але це може бути будь-який метод віджета, який приймає один аргумент.

загорнути

  Має бути одне з: `"none"`, `"char"` або `"word"`.

### Прив’язки та події

Метод прив’язки з команди віджета дозволяє спостерігати за певними подіями та запускати функцію зворотного виклику, коли відбувається подія такого типу. Форма методу прив’язки:

    def bind(self, sequence, func, add=''):

де:

послідовність

  це рядок, який позначає цільовий тип події. (Докладніше див. сторінку довідки bind(3tk) і сторінку 201 книги Джона Оустерхаута Tcl and the Tk Toolkit (2nd edition)).

функц

  це функція Python, яка приймає один аргумент, який викликається, коли відбувається подія. Екземпляр події буде передано як аргумент. (Функції, розгорнуті таким чином, широко відомі як зворотні виклики.)

додати

  є необов’язковим, або `''` або `'+'`. Передача порожнього рядка означає, що ця прив’язка має замінити будь-які інші прив’язки, з якими пов’язана ця подія. Передача `'+'` означає, що цю функцію потрібно додати до списку функцій, пов’язаних із цим типом події.

Наприклад:

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

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

Зверніть увагу, як у зворотному виклику `turn_red()` здійснюється доступ до поля віджета події. Це поле містить віджет, який перехопив подію X. У наведеній нижче таблиці перераховано інші поля подій, до яких ви можете отримати доступ, і те, як вони позначаються в Tk, що може бути корисним під час звернення до довідкових сторінок Tk.

Тк | Поле подій Tkinter | Тк | Поле подій Tkinter
--- | --- | --- | ---
%f | фокус | %A | char
%h | висота | %E | send_event
%k | код ключа | %K | keysym
%s | стан | %N | keysym_num
%t | час | %T | типу
%w | ширина | %W | віджет
%x | x | %X | x_root
%y | р | %Y | y_root

### Параметр індексу

Кілька віджетів потребують передачі параметрів «index». Вони використовуються для вказівки на певне місце у віджеті «Текст», або на певні символи у віджеті «Вхід», або на певні пункти меню у віджеті «Меню».

Індекси віджетів запису (індекс, індекс перегляду тощо)

  Entry widgets have options that refer to character positions in the text being displayed. You can use these `tkinter` functions to access these special points in text widgets:

Індекси текстових віджетів

  Нотація покажчика для текстових віджетів дуже багата і найкраще описана на сторінках керівництва Tk.

Індекси меню (menu.invoke(), menu.entryconfig() тощо)

  Деякі параметри та методи для меню маніпулюють певними записами меню. Щоразу, коли для опції чи параметра потрібен індекс меню, ви можете передати:

  - ціле число, яке відноситься до числової позиції запису у віджеті, починаючи з 0;

  - рядок `"active"`, який посилається на позицію меню, яка зараз знаходиться під курсором;

  - рядок `"last"`, який посилається на останній пункт меню;

  - Ціле число, якому передує `@`, як у `@6`, де ціле число інтерпретується як координата y пікселя в системі координат меню;

  - рядок `"none"`, який вказує на те, що в меню взагалі немає запису, найчастіше використовується з menu.activate(), щоб дезактивувати всі записи, і, нарешті,

  - текстовий рядок, який зіставляється з міткою запису меню, відсканований від верхньої частини меню донизу. Зауважте, що цей тип індексу розглядається після всіх інших, що означає, що збіги для пунктів меню, позначених як `останній`, `активний` або `жоден`, замість цього можуть інтерпретуватися як наведені вище літерали.

### Зображення

Зображення різних форматів можна створювати за допомогою відповідного підкласу `tkinter.Image`:

- `BitmapImage` для зображень у форматі XBM.

- `PhotoImage` для зображень у форматах PGM, PPM, GIF і PNG. Останній підтримується, починаючи з Tk 8.6.

Будь-який тип зображення створюється за допомогою параметра `file` або `data` (інші параметри також доступні).

Змінено в версії 3.13: Added the `PhotoImage` method `copy_replace()` to copy a region from one image to other image, possibly with pixel zooming and/or subsampling. Add from_coords parameter to `PhotoImage` methods `copy()`, `zoom()` and `subsample()`. Add zoom and subsample parameters to `PhotoImage` method `copy()`.

Потім об’єкт зображення можна використовувати скрізь, де параметр `image` підтримується деяким віджетом (наприклад, мітки, кнопки, меню). У цих випадках Tk не зберігатиме посилання на зображення. Коли останнє посилання Python на об’єкт зображення видаляється, дані зображення також видаляються, і Tk відображатиме порожнє поле, де б зображення не використовувалося.

Дивись також

The Pillow package adds support for formats such as BMP, JPEG, TIFF, and WebP, among others.

## Обробники файлів

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.