Языки программирования

Библиотека Tkinter: Методы виджетов

Все виджеты в Tkinter обладают некоторыми общими методами. В этой статье мы познакомимся с такими методами. Список всех виджетов можно изучить в статье «Библиотека Tkinter: Виджеты«.

1. configure

Виджеты могут быть сконфигурированы во время создания, но иногда необходимо изменить конфигурацию виджета во время исполнения программы.
Для этого используется метод configure (или его синоним config). Также можно использовать квадратные скобки (widget[‘option’] = new_value).
Пример, программа выводит текущее время, после клика по кнопке:
from tkinter import *
import time

def button_clicked():
    # изменяем текст кнопки
    button['text'] = time.strftime('%H:%M:%S')
    
root = Tk()
root.title("Методы виджетов")
root.minsize(width=500, height=400)

# создаём виджет
button = Button(root)

# конфигурируем виджет после создания
button.configure(text=time.strftime('%H:%M:%S'), command=button_clicked)

# также можно использовать квадратные скобки:
# button['text'] = time.strftime('%H:%M:%S')
# button['command'] = button_clicked
button.pack()
root.mainloop()
В этом коде функция button_clicked вызывается каждый раз, когда пользователь «кликает» по кнопке.

2. cget

Метод cget является обратным к методу configure. Он предназначен для получения информации о конфигурации виджета. Здесь как и в случае с configure можно использовать квадратные скобки (value = widget[‘option’]).
Рассмотрим пример:
from tkinter import *
from random import random

def button_clicked():
    button['text'] = button['bg'] # показываем предыдущий цвет кнопки
    bg = '#%0x%0x%0x' % (int(random()*16), int(random()*16), int(random()*16))
    button['bg'] = bg
    button['activebackground'] = bg
    
root = Tk()
root.title("Методы виджетов")
root.minsize(width=500, height=400)

button = Button(root, command=button_clicked)
button.pack()
root.mainloop()
В данном примере программа после «клика» на кнопку программа показывает цвет кнопки и меняет его на другой.

3. destroy

Метод destroy() уничтожает виджет и всех его потомков. Рассмотрим пример:
from tkinter import *
    
root = Tk()
root.title("Методы виджетов")
root.minsize(width=500, height=400)

button1 = Button(root, text="Кнопка 1")
button2 = Button(root, text="Нажми и удалишь кнопку 1", command = button1.destroy)

button1.pack()
button2.pack()
root.mainloop()
В данном примере мы создаем две кнопки и к одной кнопке даём команду: «При нажатии на кнопку уничтожать виджет в виде первой кнопки» с помощью метода destroy().

Главное окно программы не будет закрыто, но «Кнопка 1» будет удалена с главного окна.

Если необходимо только на время спрятать какой-либо виджет, то лучше пользоваться упаковщиком grid и методом grid_remove:
from tkinter import *

def hide_show():
    if label.winfo_viewable():
        label.grid_remove()
    else:
        label.grid()

root = Tk()
root.title("Методы виджетов")
root.minsize(width=500, height=400)

label = Label(text='Я здесь!')
label.grid()
button = Button(command=hide_show, text="Спрятать/показать")
button.grid()
root.mainloop()
Использование grid_remove позволяет сохранять взаимное расположение виджетов.

4. quit

Метод quit() не уничтожает виджеты, но выходит из интерпретатора tcl/tk, то есть останавливает mainloop(). Пример:
from tkinter import *
    
root = Tk()
root.title("Методы виджетов")
root.minsize(width=500, height=400)

# При нажатии на кнопку программа закроется.
button = Button(root, text="Закрыть программу", command = root.quit)

button.pack()
root.mainloop()

5. grab_

Методы семейства grab_ предназначены для управления потоком события. Виджет, захвативший поток, будет получать все события окна или приложения.
  • grab_set — передать поток данному виджету;
  • grab_set_global — передать глобальный поток данному виджету. В этом случае все события на дисплее будут передаваться этому виджету. Следует пользоваться очень осторожно, т.к. остальные виджеты всех приложений не будут получать события;
  • grab_release — освободить поток;
  • grab_status — узнать текущий статус потока событий для виджета. Возможные значения: None, «local» или «global»;
  • grab_current — получить виджет, который получает поток.
Пример, приложение захватывает глобальный поток и освобождает его через 10 секунд:
from tkinter import *

root=Tk()
root.after(200, root.grab_set_global)
root.after(10000, root.grab_release)
root.mainloop()

6. focus_

Методы семейства focus_ используются для управления фокусом ввода с клавиатуры. Виджет, имеющий фокус, получает все события с клавиатуры.
  • focus (синоним focus_set) — передать фокус виджету;
  • focus_force — передать фокус, даже если приложение не имеет фокуса;
  • focus_get — возвращает виджет, на который направлен фокус, либо None, если такой отсутствует;
  • focus_displayof — возвращает виджет, на который направлен фокус на том дисплее, на котором размещён виджет, либо None, если такой отсутствует;
  • focus_lastfor — возвращает виджет, на который будет направлен фокус, когда окно с этим виджетом получит фокус;
  • tk_focusNext — возвращает виджет, который получит фокус следующим (обычно смена фокуса происходит при нажатии клавиши Tab). Порядок следования определяется последовательностью упаковки виджетов;
  • tk_focusPrev — то же, что и focusNext, но в обратном порядке;
  • tk_focusFollowsMouse — устанавливает, что виджет будет получать фокус при наведении на него мышью. Вернуть нормальное поведение достаточно сложно.
Рассмотрим пример:
from tkinter import *

root = Tk()
root.title("Методы виджетов")
root.minsize(width=500, height=400)

# Виджет входа
e1 = Entry(root)
e1.pack(expand = 1, fill = BOTH)

# Виджет кнопки, который в данный момент имеет фокус
e2 = Button(root, text ="Button")

# здесь метод focus_set () используется для установки фокуса
e2.focus_set()
e2.pack(pady = 5)
root.mainloop()
Перепишете код и запустите для проверки. В главном окне будет стоять кнопка и иметь фокус.

7. Системные методы

Системные методы не являются виджет-специфичными, т.е. хотя они являются методами виджетов они влияют на работу интерпретатора tcl/tk.

1. after, after_idle и after_cancel

Таймеры. С помощью этих методов вы можете отложить выполнение какого-нибудь кода на определённое время.
after — принимает два аргумента: время в миллисекундах и функцию, которую надо выполнить через указанное время. Возвращает идентификатор, который может быть использован в after_cancel.
after_idle — принимает один аргумент — функцию. Эта функция будет выполнена после завершения всех отложенных операций (после того, как будут обработаны все события). Возвращает идентификатор, который может быть использован в after_cancel.
after_cancel — принимает один аргумент: идентификатор задачи, полученный предыдущими функциями, и отменяет это задание.
Рассмотрим пример:
from tkinter import *
import time

def tick():
    label.after(200, tick)
    label['text'] = time.strftime('%H:%M:%S')

root = Tk()
root.title("Методы виджетов")
root.minsize(width=500, height=400)

label = Label(font='sans 20')
label.pack()
label.after_idle(tick)
root.mainloop()

2. update и update_idletasks

Две функции, для работы с очередью задач. Их выполнение вызывает обработку отложенных задач.
update_idletasks выполняет задачи, обычно откладываемые «на потом», когда приложение будет простаивать. Это приводит к прорисовке всех виджетов, расчёту их расположения и т.д.
Обычно эта функция используется если были внесены изменения в состояние приложения, и вы хотите, чтобы эти изменения были отображены на экране немедленно, не дожидаясь завершения сценария.
update обрабатывает все задачи, стоящие в очереди. Обычно эта функция используется во время «тяжёлых» расчётов, когда необходимо чтобы приложение оставалось отзывчивым на действия пользователя.
Пример:
from tkinter import *
import math

def hard_job():
    x = 1000
    while True:
        x = math.log(x) ** 2.8
        root.update()
        print(x)
        break

root = Tk()
root.title("Методы виджетов")
root.minsize(width=500, height=400)

button = Button(text="Обновить", command = hard_job)
button.pack()
root.after(500, hard_job)
root.mainloop()

3. eval и evalfile

Две недокументированные функции для выполнения кода на tcl.
eval позволяет выполнить строку на языке программирования tcl.
evalfile — выполнить код, записанный в файл.
В качестве аргументов принимают соответственно строку и путь к файлу. Данные функции полезны при использовании дополнительных модулей, написанных на tcl. Пример:
from tkinter import *

root = Tk()
root.title("Методы виджетов")
root.minsize(width=500, height=400)

root.eval('package require tile; ttk::style theme use clam')
root.eval('ttk::button .b -text {ttk button}; pack .b')
root.mainloop()
Библиотека Tkinter