Python tkinter ttk frame

Модуль tkinter.ttk

В состав пакета tkinter входит модуль ttk , содержащий классы более стилизованных и современных виджет. По умолчанию их внешний вид зависит от операционной системы.

В коде ниже для сравнения в окне размещено несколько пар аналогичных виджетов из модулей tkinter и tkinter.ttk .

import tkinter as tk import tkinter.ttk as ttk root = tk.Tk() tk.Button(text="Hello").pack() ttk.Button(text="Hello").pack() tk.Checkbutton(text="Hello").pack() ttk.Checkbutton(text="Hello").pack() tk.Radiobutton(text="Hello").pack() ttk.Radiobutton(text="Hello").pack() root.mainloop()

В операционной системе Ubuntu они будут выглядеть так:

Поскольку имена классов аналогичных виджетов совпадают, мы импортируем модули так, чтобы их пространства имен не перекрывались. При этом конструкторы классов вызываются через имена (в данном случае псевдонимы) модулей.

Если же нам не нужны виджеты модуля tkinter , подобные которым есть в tkinter.ttk , удобнее импортировать всё пространство имен как одного, так и второго модуля.

from tkinter import * from tkinter.ttk import * root = Tk() b = Button(text="Hello") b.pack() t = Text(width=10, height=5) t.pack() print(root.__class__) print(b.__class__) print(t.__class__) root.mainloop()

В данном случае пространство имен tkinter.ttk , который импортируется вторым, перекрывает часть имен tkinter . Поэтому выражение Button(text=»Hello») вызывает конструктор класса Button , находящийся в модуле tkinter.ttk . В то же время в этом модуле нет классов Tk и Text . Следовательно, экземпляры этих классов создаются от базовых классов tkinter . В консоль будет выведено:

Как уже должно быть понятно, наборы виджетов обоих модулей не полностью перекрываются. Есть общие (такие как Label , Button , Entry ), есть характерные только для tkinter (например, Listbox и Canvas ) и только для ttk (например, Combobox , Notebook ).

Читайте также:  Kotlin sqlite android studio

Сложность заключается в том, что в ttk свойства виджетов программируются не совсем так как в tkinter . Если в приложении сочетаются элементы сразу обоих модулей, код программы становится менее ясным.

Для виджетов из tkinter.ttk многие свойства задаются с помощью экземпляра, созданного от класса ttk.Style . Основная идея ttk – отделить оформление виджета от описания его поведения.

Импортируем модули, не перекрывая пространства их имен, и сравним установку свойств для двух кнопок.

from tkinter import * from tkinter import ttk root = Tk() b_tk = Button(text="Hello Tk") b_ttk = ttk.Button(text="Hello Ttk") b_tk.config(background="#b00", foreground="#fff") style = ttk.Style() style.configure("TButton", background="#0b0", foreground="#fff") b_tk.pack(padx=10, pady=10) b_ttk.pack(padx=10, pady=10) root.mainloop()

Мы задаем свойства для экземпляра Button из модуля tkinter с помощью метода кнопки config . Однако то же самое могли бы сделать, передав значения в конструктор:

b_tk = Button(text="Hello Tk", background="#b00", foreground="#fff")

Настроить так кнопку из модуля ttk нельзя. Вместо этого мы должны создать экземпляр от класса Style и уже через него изменять свойства по умолчанию.

В коде выше используется метод configure . Здесь первым аргументом в него передается имя стиля ( TButton ), связанного с классом объектов, для которых производится настройка. В данном случае это кнопки. Для уточнения имени стиля можно воспользоваться методом winfo_class :

print(ttk.Label().winfo_class()) print(ttk.Button().winfo_class())

Что делать, если в программе нужны, например, кнопки разного стиля? Можно создать свой стиль, унаследовав его от исходного, и изменять лишь отдельные свойства.

from tkinter import * from tkinter.ttk import * root = Tk() style = Style() style.configure("G.TButton", foreground="green") Button(text="First", style="G.TButton").pack() Button(text="Second").pack() root.mainloop()

В примере выше созданный стиль называется «G». После точки указывается его родитель (в данном случае это стиль TButton . При создании первой кнопки через опцию style указываем применяемый стиль.

По-умолчанию для второй кнопки используется стиль TButton . Мы его не меняли, хотя могли бы изменить.

На самом деле острой или частой необходимости изменять внешний вид виджетов нет. Наоборот, в приложениях приветствуется стандартный и единообразный внешний вид и поведение. Это дает пользователю интуитивно понятный интерфейс.

Кроме того, в ttk есть разные темы. Можно менять не отдельные виджеты, а целиком тему оформления приложения. С помощью методов theme_names и theme_use можно выяснить список тем (который зависит от вашей ОС) и текущую тему:

from tkinter.ttk import * style = Style() print(style.theme_names()) print(style.theme_use())
('clam', 'alt', 'default', 'classic') default

Если в метод theme_use передать название темы, она будет применена. В программе ниже при нажатии клавиши Enter изменяется тема приложения:

from tkinter import * from tkinter.ttk import * root = Tk() style = Style() e = Entry(justify='center') e.pack() Button(text="Hello").pack() Label(text="Hello").pack() themes = style.theme_names() i = 0 def theme_next(event): global i style.theme_use(themes[i]) e.delete(0, END) e.insert(0, themes[i]) if i  len(themes)-1: i += 1 else: i = 0 root.bind('', theme_next) root.mainloop()

Описание свойств виджетов в ttk не всегда совпадает с тем, как это делается в базовом tkinter . Выше в примере с красной и зеленой кнопками с помощью опций foreground и background мы устанавливаем цвета текста и фона кнопки, когда она не находится под курсором мыши, то есть когда она не активна.

Чтобы переопределить цвета по умолчанию при наводе курсора, для кнопок tkinter мы должны использовать опции activeforeground и activebackground . Однако эти свойства не работают для виджетов из ttk :

… b_tk.config(background="red", foreground="white", activebackground="orange", activeforeground="white") style = ttk.Style() style.configure("TButton", background="green", foreground="white", activebackground="lightgreen", activeforeground="black")

Код выше выполнится без ошибок. Однако фон зеленой кнопки при нажатии на нее останется светло-серым, он не станет светло-зеленым.

В данном случае вместо метода configure следует использовать метод map объектов типа Style :

from tkinter import * from tkinter.ttk import * root = Tk() Button(text="Hello World").pack( padx=40, pady=40, ipadx=20, ipady=20 ) st = Style() st.map('TButton', foreground=[('!active', 'purple'), ('pressed', 'orange'), ('active', 'red')], background=[ ('pressed', 'brown'), ('active', 'white')] ) root.mainloop()

Состояния кнопки: !active, active, pressed

Здесь мы описываем для кнопки состояния двух свойств: текста ( foreground ) и фона ( background ). При этом у каждого свойства есть три состояния: неактивно, активно и нажато.

Практическая работа

Напишите программу, состоящую из выпадающего списка ( Combobox ) и холста. В списке перечисляются цвета. При выборе в списке того или иного значения цвет холста должен изменяться на соответствующий.

Combobox

  • Список значений передается в Combobox через опцию values .
  • Метод current экземпляра Combobox позволяет указать значение, которое будет выбрано в списке изначально. Метод принимает индекс элемента из списка значений.
  • Событие смены значения в выпадающем списке – ‘>’
  • Метод get экземпляра Combobox возвращает выбранный на данный момент элемент списка.

Курс с примерами решений практических работ: pdf-версия

Tkinter. Программирование GUI на Python

Источник

Tkinter 8.5 reference: a GUI for Python

Like the Tkinter Frame widget, the ttk .Frame widget is a rectangular container for other widgets. To create a Frame widget as the child of a given parent widget:

w = ttk.Frame(parent, option=value, . )

Table 42. ttk .Frame options

Use this option to specify whether a widget is visited during focus traversal; see Section 53, “Focus: routing keyboard input”. Specify takefocus=True if you want the visit to accept focus; specify takefocus=False if the widget is not to accept focus. The default value is an empty string; by default, ttk .Frame widgets do not get focus.

These options on the Tkinter Frame widget are not available as options on the ttk .Frame constructor:

Table 43. Tkinter Frame options not in ttk .Frame

background or bg Configure this option with a style; see Section 47, “Customizing and creating ttk themes and styles”.
highlightbackground To control the color of the focus highlight when the frame does not have focus, use a style map to control the highlightcolor option; see Section 50.2, “ ttk style maps: dynamic appearance changes”.
highlightcolor You may specify the default focus highlight color by setting this option in a style. You may also control the focus highlight color using a style map.
highlightthickness Configure this option using a style. This option may not work in all themes.
padx Not supported.
pady Not supported.

Источник

Оцените статью