а также смотрите приведенный Ниже пример, который создает экземпляры Tk последовательно, а не сразу, так что в любой момент времени существует ровно один экземпляр Tk:
Почему считается плохим иметь несколько экземпляров Tk?
Считается ли второй фрагмент немного лучше, или он страдает от тех же условий, что и первый код?
Переведено автоматически
Ответ 1
Почему считается плохим иметь несколько экземпляров Tk?
Tkinter - это просто оболочка python для встроенного интерпретатора Tcl, которая импортирует библиотеку Tk. Когда вы создаете корневое окно, вы создаете экземпляр интерпретатора Tcl.
Каждый интерпретатор Tcl представляет собой изолированную изолированную среду. Объект в одной изолированной среде не может взаимодействовать с объектами в другой. Наиболее распространенным проявлением этого является то, что StringVar созданный в одном интерпретаторе, не виден в другом. То же самое касается виджетов - вы не можете создавать виджеты в одном интерпретаторе, который имеет родительский виджет в другом интерпретаторе. Третий случай - изображения: изображения, созданные в одном, не могут быть использованы в другом.
С технической точки зрения, нет причин, по которым у вас не может быть двух экземпляров Tk одновременно. Рекомендация против этого заключается в том, что редко возникает реальная необходимость в наличии двух или более различных интерпретаторов Tcl, и это вызывает проблемы, которые новичкам трудно понять.
Считается ли второй фрагмент немного лучше, или он страдает от тех же условий, что и первый код?
Невозможно сказать, лучше ли второй пример в вопросе или нет, не зная, чего вы пытаетесь достичь. Вероятно, это ничуть не лучше, поскольку, опять же, редко бывает момент, когда вам действительно нужны два экземпляра.
Лучшим решением в 99,9% случаев является создание ровно одного экземпляра Tk, который вы используете на протяжении всего срока службы вашей программы. Если вам нужно второе или последующее окно, создайте экземпляры Toplevel. Проще говоря, именно для этого был разработан tkinter и лежащий в его основе интерпретатор Tcl / Tk.
Ответ 2
Я не согласен с tkinter сообществом, которое не рекомендует использовать несколько tk.Tk окон. У вас может быть несколько tk.Tk окон. Использование нескольких экземпляров tk.Tk - это единственный способ создать окна, которые действительно независимы друг от друга. Единственная ошибка, которую большинство людей допускают при создании нескольких tk.Tk окон, заключается в том, что они забывают ввести master=... при создании PhotoImage s /StringVars /IntVars /...
Для примера посмотрите на этот код:
import tkinter as tk
root = tk.Tk() root2 = tk.Tk()
variable = tk.StringVar() # Add `master=root2` to fix the problem entry = tk.Entry(root2, textvariable=variable) entry.bind("<Return>", lambda e: print(repr(variable.get()))) entry.pack()
root.mainloop()
Приведенный выше код не работает. Если вы добавите master=root2 в tk.StringVar(), то он будет работать совершенно нормально. Это потому, что tkinter хранит первый экземпляр tk.Tk() в tk._default_root. Тогда, если вы не передадите его master=..., будет предположено, что вы хотели использовать окно tk._default_root.
Еще одна вещь, в которой люди ошибаются, - это сколько раз следует .mainloop() вызываться. Он обрабатывает события из всех tk.Tk работающих окон, поэтому вам нужно только одно .mainloop().
Для тех, кто не согласен, мне было бы интересно привести пример того, где реальная проблема вызвана несколькими tk.Tk окнами.
В простых примерах, которые мы использовали до сих пор, на экране отображается только одно окно; корневое окно. Оно создается автоматически при вызове конструктора Tk
и
Если вам нужно создать дополнительные окна, вы можете использовать виджет верхнего уровня. Это просто создает новое окно на экране, окно, которое выглядит и ведет себя почти так же, как исходное корневое окно
Я считаю, что Tk экземпляр создает Toplevel виджет плюс такие вещи, как mainloop, из которых должен быть только один.
Ответ 4
Tk() инициализирует скрытый интерпретатор tcl, чтобы код мог выполняться, поскольку Tkinter - это просто оболочка для tcl / tk . Он также автоматически создает новое окно. Toplevel() просто создает новое окно и не будет работать, если Tk() экземпляр не был создан, поскольку для этого требуется интерпретатор tcl, который Tk() инициализирует. Вы не можете создавать виджеты Tkinter без создания экземпляра Tk(), а Toplevel - это просто виджет. В вопросе вы используете Tk() для создания второго окна. Вместо этого вам следует создать другой файл, потому что многократная инициализация интерпретатора tcl может привести к путанице, как так хорошо объясняет @Bryan Oakley. Затем вам следует сделать:
from os import startfile startfile(nameOfTheOtherFile)
, поскольку Toplevel() это всего лишь виджет, он закрывается при закрытии Tk() окна. Наличие другого окна в отдельном файле делает его менее запутанным.