为什么不鼓励使用 Tk 的多个实例?
- 2024-11-21 08:33:00
- admin 原创
- 3
问题描述:
考虑下面的例子:
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
?第二段代码是否更好一些,或者它是否面临与第一段代码相同的情况?
解决方案 1:
为什么拥有多个实例被认为是不好的
Tk
?
Tkinter 只是一个嵌入 Tcl 解释器的 Python 包装器,它导入了 Tk 库。创建根窗口时,会创建 Tcl 解释器的实例。
每个 Tcl 解释器都是一个独立的沙箱。一个沙箱中的对象不能与另一个沙箱中的对象交互。最常见的表现是,StringVar
在一个解释器中创建的对象在另一个解释器中不可见。小部件也是如此——您不能在一个解释器中创建另一个解释器中作为父小部件的小部件。图像是第三种情况:在一个解释器中创建的图像不能在另一个解释器中使用。
从技术角度来看,没有理由不能Tk
同时拥有两个实例。不建议这样做是因为实际上很少需要拥有两个或更多不同的 Tcl 解释器,而且这会导致初学者难以理解的问题。
第二段代码是否更好一些,或者它是否面临与第一段代码相同的情况?
如果不知道您要实现什么,就无法判断问题中的第二个示例是否更好。它可能并没有什么更好,因为您很少真正需要两个实例。
99.9% 的最佳解决方案是只创建一个实例,Tk
供程序使用。如果您需要第二个或后续窗口,请创建实例Toplevel
。很简单,这就是 tkinter 和底层 Tcl/Tk 解释器的设计用途。
解决方案 2:
我不同意tkinter
社区不鼓励使用多个tk.Tk
窗口。您可以拥有多个tk.Tk
窗口。使用多个实例tk.Tk
是创建真正相互独立的窗口的唯一方法。大多数人在创建多个窗口时犯的唯一错误是他们忘记在创建s/ s/ s/...时tk.Tk
传入master=...
`PhotoImageStringVar
IntVar`
例如看看这个代码:
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_rootmaster=...
tk._default_root`
.mainloop()
人们犯的另一个错误是应该调用多少次。它处理来自所有tk.Tk
活动窗口的事件,因此您只需要一个.mainloop()
。
对于那些不同意的人,我感兴趣的是一个由多个窗口导致实际问题的例子tk.Tk
。
解决方案 3:
到目前为止我发现的最佳参考是tkinterbook的应用程序窗口部分:
在我们迄今为止使用的简单示例中,屏幕上只有一个窗口;根窗口。当您调用Tk构造函数时,它将自动创建
和
如果需要创建其他窗口,可以使用Toplevel小部件。它只是在屏幕上创建一个新窗口,该窗口的外观和行为与原始根窗口非常相似
我的看法是,一个Tk
实例会创建一个Toplevel
小部件,以及诸如此类的东西mainloop
,其中应该只有一个。
解决方案 4:
Tk()
初始化隐藏的 tcl 解释器,以便代码可以运行,因为 Tkinter 只是 tcl/tk 的包装器。它还会自动创建一个新窗口。只创建一个新窗口,如果尚未实例化,Toplevel()
它将无法工作,因为它需要初始化的 tcl 解释器。您无法在不实例化的情况下创建任何 Tkinter 小部件,而 Toplevel 只是一个小部件。在问题中,您使用来创建第二个窗口。您应该创建另一个文件,因为多次初始化 tcl 解释器可能会造成混淆,正如@Bryan Oakley 很好地解释的那样。然后你应该这样做:Tk()
`Tk()Tk()
Tk()`
`from os import startfile
startfile(nameOfTheOtherFile)`
,因为,它Toplevel()
只是一个小部件,当Tk()
窗口关闭时,它也会关闭。将另一个窗口放在单独的文件中可以减少混乱。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件