为什么不鼓励使用多个 Tk 实例?
Why are multiple instances of Tk discouraged?
考虑以下示例:
import tkinter as tk
root = tk.Tk()
root.title("root")
other_window = tk.Tk()
other_window.title("other_window")
root.mainloop()
另请参见下面的示例,该示例连续创建 Tk
实例而不是一次创建实例,因此 恰好有一个 实例 Tk
在任何给定时间:
import tkinter as tk
def create_window(window_to_be_closed=None):
if window_to_be_closed:
window_to_be_closed.destroy()
window = tk.Tk()
tk.Button(window, text="Quit", command=lambda arg=window : create_window(arg)).pack()
window.mainloop()
create_window()
- 为什么
Tk
的多个实例被认为是不好的?
- 第二个片段是被认为更好一点,还是受到了影响
第一个代码的条件相同吗?
到目前为止我找到的最好的参考是 Application Windows section of the tkinterbook:
In the simple examples we’ve used this far, there’s only one window on the screen; the root window. This is automatically created when you call the Tk constructor
和
If you need to create additional windows, you can use the Toplevel widget. It simply creates a new window on the screen, a window that looks and behaves pretty much like the original root window
我的看法是,Tk
实例会创建一个 Toplevel
小部件,加上 mainloop
之类的东西,其中应该只有一个。
Why is it considered bad to have multiple instances of Tk
?
Tkinter 只是一个 python 围绕导入 Tk 库的嵌入式 Tcl 解释器的包装器。当您创建一个根 window 时,您创建了一个 Tcl 解释器的实例。
每个 Tcl 解释器都是一个独立的沙箱。一个沙箱中的对象不能与另一个沙箱中的对象交互。最常见的表现是在一个解释器中创建的 StringVar
在另一个解释器中不可见。小部件也是如此——您不能在一个解释器中创建小部件,而在另一个解释器中将其作为父小部件。图片是第三种情况:在一个中创建的图像不能在另一个中使用。
从技术角度来看,没有理由不能同时拥有两个 Tk
实例。反对它的建议是因为很少有实际需要有两个或更多不同的 Tcl 解释器,并且它会导致初学者难以掌握的问题。
Is the second snippet considered a bit better, or does it suffer from the same conditions the first code does?
如果不知道您要实现的目标,就不可能说问题中的第二个示例是否更好。它可能也好不到哪儿去,因为再说一遍,您很少会真正需要两个实例。
99.9% 的最佳解决方案是只创建一个 Tk
的实例,供您在程序的整个生命周期中使用。如果您需要第二个或后续 window,请创建 Toplevel
的实例。很简单,这就是 tkinter 和底层 Tcl/Tk 解释器的设计用途。
Tk()
初始化隐藏的 tcl 解释器,以便代码可以 运行,因为 Tkinter 只是 tcl/tk 的包装器。它还会自动创建一个新的 window。 Toplevel()
只是创建一个新的 window,如果 Tk()
没有被实例化,它将无法工作,因为它需要 Tk()
初始化的 tcl 解释器。您不能在不实例化 Tk()
的情况下创建任何 Tkinter 小部件,并且 Toplevel 只是一个小部件。在问题中,您使用 Tk()
创建第二个 window。您应该创建另一个文件,因为多次初始化 tcl 解释器可能会造成混淆,正如@Bryan Oakley 解释的那样。那么你应该这样做:
from os import startfile
startfile(nameOfTheOtherFile)
,因为 Toplevel()
只是一个小部件,它会在 Tk()
window 关闭时关闭。将另一个 window 放在单独的文件中可以减少混淆。
我不同意 tkinter
社区不鼓励使用多个 tk.Tk
windows。您可以有多个 tk.Tk
windows。使用 tk.Tk
的多个实例是创建真正相互独立的 windows 的唯一方法。大多数人在创建多个 tk.Tk
windows 时犯的唯一错误是他们在创建 PhotoImage
s/StringVar
s/[=19 时忘记传入 master=...
=]s/...
例如看这段代码:
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
.
中的 window
人们误解的另一件事是应该调用 .mainloop()
多少次。它处理来自所有 tk.Tk
windows 的活动事件,因此您只需要一个 .mainloop()
.
对于不同意的人,我会对一个实际问题是由多个 tk.Tk
windows.
引起的示例感兴趣
考虑以下示例:
import tkinter as tk
root = tk.Tk()
root.title("root")
other_window = tk.Tk()
other_window.title("other_window")
root.mainloop()
另请参见下面的示例,该示例连续创建 Tk
实例而不是一次创建实例,因此 恰好有一个 实例 Tk
在任何给定时间:
import tkinter as tk
def create_window(window_to_be_closed=None):
if window_to_be_closed:
window_to_be_closed.destroy()
window = tk.Tk()
tk.Button(window, text="Quit", command=lambda arg=window : create_window(arg)).pack()
window.mainloop()
create_window()
- 为什么
Tk
的多个实例被认为是不好的? - 第二个片段是被认为更好一点,还是受到了影响 第一个代码的条件相同吗?
到目前为止我找到的最好的参考是 Application Windows section of the tkinterbook:
In the simple examples we’ve used this far, there’s only one window on the screen; the root window. This is automatically created when you call the Tk constructor
和
If you need to create additional windows, you can use the Toplevel widget. It simply creates a new window on the screen, a window that looks and behaves pretty much like the original root window
我的看法是,Tk
实例会创建一个 Toplevel
小部件,加上 mainloop
之类的东西,其中应该只有一个。
Why is it considered bad to have multiple instances of
Tk
?
Tkinter 只是一个 python 围绕导入 Tk 库的嵌入式 Tcl 解释器的包装器。当您创建一个根 window 时,您创建了一个 Tcl 解释器的实例。
每个 Tcl 解释器都是一个独立的沙箱。一个沙箱中的对象不能与另一个沙箱中的对象交互。最常见的表现是在一个解释器中创建的 StringVar
在另一个解释器中不可见。小部件也是如此——您不能在一个解释器中创建小部件,而在另一个解释器中将其作为父小部件。图片是第三种情况:在一个中创建的图像不能在另一个中使用。
从技术角度来看,没有理由不能同时拥有两个 Tk
实例。反对它的建议是因为很少有实际需要有两个或更多不同的 Tcl 解释器,并且它会导致初学者难以掌握的问题。
Is the second snippet considered a bit better, or does it suffer from the same conditions the first code does?
如果不知道您要实现的目标,就不可能说问题中的第二个示例是否更好。它可能也好不到哪儿去,因为再说一遍,您很少会真正需要两个实例。
99.9% 的最佳解决方案是只创建一个 Tk
的实例,供您在程序的整个生命周期中使用。如果您需要第二个或后续 window,请创建 Toplevel
的实例。很简单,这就是 tkinter 和底层 Tcl/Tk 解释器的设计用途。
Tk()
初始化隐藏的 tcl 解释器,以便代码可以 运行,因为 Tkinter 只是 tcl/tk 的包装器。它还会自动创建一个新的 window。 Toplevel()
只是创建一个新的 window,如果 Tk()
没有被实例化,它将无法工作,因为它需要 Tk()
初始化的 tcl 解释器。您不能在不实例化 Tk()
的情况下创建任何 Tkinter 小部件,并且 Toplevel 只是一个小部件。在问题中,您使用 Tk()
创建第二个 window。您应该创建另一个文件,因为多次初始化 tcl 解释器可能会造成混淆,正如@Bryan Oakley 解释的那样。那么你应该这样做:
from os import startfile
startfile(nameOfTheOtherFile)
,因为 Toplevel()
只是一个小部件,它会在 Tk()
window 关闭时关闭。将另一个 window 放在单独的文件中可以减少混淆。
我不同意 tkinter
社区不鼓励使用多个 tk.Tk
windows。您可以有多个 tk.Tk
windows。使用 tk.Tk
的多个实例是创建真正相互独立的 windows 的唯一方法。大多数人在创建多个 tk.Tk
windows 时犯的唯一错误是他们在创建 PhotoImage
s/StringVar
s/[=19 时忘记传入 master=...
=]s/...
例如看这段代码:
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
windows 的活动事件,因此您只需要一个 .mainloop()
.
对于不同意的人,我会对一个实际问题是由多个 tk.Tk
windows.