На этом шаге мы рассмотрим класс, отвечающий за создание вторичных окон, и приведем пример его использования.
Обычное вторичное окно существует относительно независимо от главного окна и других обычных вторичных окон. Пользователь может свободно переключаться между окнами такого типа.
Обычное вторичное окно создается точно таким же образом, как и главное, но представляется классом Toplevel из модуля tkinter. Конструктор этого класса вызывается в следующем формате:
Toplevel([<Параметры>])
Из всех поддерживаемых конструктором параметров для нас наиболее интересны следующие:
wnd = tkinter.Toplevel(width=400, height=300)
wnd = tkinter.Toplevel(background="blue")
В качестве значения можно указать пустую строку - тогда создаваемое вторичное окно не будет иметь ни фона, ни рамки.
Если параметр вообще не указан, окно будет иметь цвет фона по умолчанию.
Класс вторичного окна Toplevel поддерживает те же методы, что и класс главного окна Tk (см. 22 шаг).
После создания окна следует создать экземпляр класса контейнера с необходимыми элементами управления, передав его конструктору в параметре master ссылку на только что созданное вторичное окно. В следующем примере Secondary - класс контейнера:
sw = Secondary(master=wnd)
Вызывать метод mainloop() окна в этом случае не нужно, так как цикл обработки сообщений уже запущен.
Сразу после вывода вторичное окно не становится активным автоматически (активным остается окно, которое его вывело). Чтобы активизировать вторичное окно, у самого окна или у помещенного в него контейнера следует вызвать метод focus_set() (который мы рассмотрим позднее):
class Secondary(tkinter.ttk.Frame): def __init__(self, master=None): . . . self.focus_set()
Пример ниже содержит код приложения, использующего вторичное окно для занесения значения, выводимого в главном окне. В главном окне располагаются кнопка Вывести окно, открывающая вторичное окно, и надпись, в которой выводится значение, занесенное во вторичном окне. В последнем же располагаются поле ввода и кнопка Вывести значение.
import tkinter import tkinter.ttk # Объявляем класс контейнера для вторичного окна class Secondary(tkinter.ttk.Frame): # Конструктор этого класса поддерживает дополнительный параметр # parent, с которым передается ссылка на главное окно. Она # понадобится нам, чтобы вывести занесенное значение в главном окне def __init__(self, master=None, parent=None): super().__init__(master) # Сохраним ссылку на главное окно в атрибуте self.parent = parent self.pack() self.create_widgets() self.master.title("Вторичное окно") self.master.resizable(False, False) # He забываем принудительно активизировать выведенное окно self.focus_set() def create_widgets(self): self.varValue = tkinter.StringVar() self.varValue.set("Значение") entValue = tkinter.ttk.Entry(self, textvariable=self.varValue) entValue.pack() btnShow = tkinter.ttk.Button(self, text="Вывести значение", command=self.show_value) btnShow.pack() def show_value(self): self.parent.lblValue["text"] = self.varValue.get() class Application(tkinter.ttk.Frame): def __init__(self, master=None): super().__init__(master) self.pack() self.create_widgets() self.master.title("Обычные вторичные окна") self.master.resizable(False, False) def create_widgets(self): btnShowWindow = tkinter.ttk.Button(self, text="Вывести окно", command=self.show_window) btnShowWindow.pack() # Опция width компонента Label задает ширину надписи # в символах текста self.lblValue = tkinter.ttk.Label(self, text="", width=50) self.lblValue.pack() def show_window(self): # Выводим вторичное окно, не забыв указать в параметре parent # конструктора ссыпку на главное окно Secondary(master=tkinter.Toplevel(), parent=self) root = tkinter.Tk() app = Application(master=root) root.mainloop()
Результат работы приложения приведен на рисунке 1.
Рис.1. Результат работы приложения
На следующем шаге мы рассмотрим вывод модальных вторичных окон.