Что на самом деле делает вызов Tk ()?
я чистил на Tkinter, когда я посмотрел на минимальный пример из NMT Tkinter 8.5 ссылка.
#!/usr/bin/env python
import tkinter as tk
class Application(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.grid()
self.createWidgets()
def createWidgets(self):
self.quitButton = tk.Button(self, text='Quit',command=self.quit)
self.quitButton.grid()
app = Application()
app.master.title('Sample application')
app.mainloop()
все хорошо и хорошо, пока я не замечу, что Tk
класс не инициализируется. В других онлайн-справочных материалах я мог найти (ссылка на библиотеку Python, effbot.org, TkDocs), обычно есть вызов root = tk.Tk()
, из которого построены остальные примеры. Я тоже не видел никакой ссылки на Tk
инициализация класса в любом месте ссылки NMT.
информация, которую я мог бы получить относительно Tk
класс также расплывчат, а ссылка Python только перечисляет его как " виджет верхнего уровня ... который обычно является главным окном приложения". Наконец, если я заменю последние строки в фрагменте, который я представил ранее:
root = tk.Tk()
app = Application(root)
программа будет работать так же, как и раньше. Помня обо всем этом, я ... интересно знать это:
- что вызов
root = tk.Tk()
на самом деле (как в, что инициализируется) и почему предыдущий фрагмент может работать без него? - столкнусь ли я с какими-либо ловушками или ограничениями, если я не позвоню
Tk()
и просто построил мое приложение вокругFrame
класса?
3 ответов
Tkinter работает, запустив интерпретатор tcl/tk под обложками, а затем переведя команды tkinter в команды tcl/tk. Главное окно и этот интерпретатор внутренне связаны, и оба необходимы для работы приложения tkinter.
создание экземпляра Tk
инициализирует этот интерпретатор и создает корневое окно. Если вы явно не инициализируете его, он будет неявно создан при создании первого виджета.
Я не подумайте, что есть какие-то подводные камни, не инициализируя его самостоятельно, но, как утверждает Дзен python, "явное лучше, чем неявное". Ваш код будет немного легче понять, если вы явно создадите экземпляр Tk
. Это, например, помешает другим людям задавать тот же вопрос о вашем коде, который вы только что задали об этом другом коде.
Брайан Окли ответ на месте. Создание виджета будет имплицитно создайте экземпляр интерпретатора tcl/tk. Однако я хотел бы добавить некоторые фрагменты кода, чтобы лучше понять, как ТК создается неявно.
всякий раз, когда создается объект виджета (будь то кадр или кнопка или даже виджет на основе ttk),BaseWidget
класса __init__
вызывается метод, который, в свою очередь, называет _setup
метод. Вот фрагмент соответствующая часть:
def _setup(self, master, cnf):
"""Internal function. Sets up information about children."""
if _support_default_root:
global _default_root
if not master:
if not _default_root:
_default_root = Tk()
master = _default_root
self.master = master
self.tk = master.tk
и _support_default_root
и _default_root
являются глобальными переменными, объявленными в строках 132-133 на tkinter
пакета. Они инициализируются следующими значениями:
_support_default_root = 1
_default_root = None
это означает, что если master
не предоставляется, и если интерпретатор еще не был создан, экземпляр Tk
создается и назначается в качестве корня по умолчанию для всех будущих виджеты.
там тоже что-то интересное при создании пример Tk
класса. Следующий фрагмент происходит из Tk._loadtk
способ:
if _support_default_root and not _default_root:
_default_root = self
это означает, что независимо от того, как Tk
класс инициализируется, он всегда настраивается как корень по умолчанию.
иногда некоторые виджеты работать Tk()
по собственному желанию. Но я не знаю, какие виджеты и почему.
иногда она работает даже если вы не используете mainloop()
- в основном на Windows.
Tkinter странная обертка на Tcl /Tk:)
но я предпочитаю использовать root = Tk()
и root.mainloop()
всегда.