为什么不鼓励多个Tk实例?

Nae*_*Nae 5 python tk-toolkit tkinter tcl

考虑下面的例子:

import tkinter as tk

root = tk.Tk()
root.title("root")

other_window = tk.Tk()
other_window.title("other_window")

root.mainloop()
Run Code Online (Sandbox Code Playgroud)

并且还看到下面的示例,它创建了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()
Run Code Online (Sandbox Code Playgroud)
  • 为什么多个实例被认为是坏的Tk
  • 第二个片段是否被认为更好一点,或者它是否受到与第一个代码相同条件的影响?

Bry*_*ley 10

为什么多个实例被认为是坏的Tk

Tkinter只是一个嵌入式Tcl解释器的python包装器,可以导入Tk库.创建根窗口时,将创建Tcl解释器的实例.

每个Tcl解释器都是一个独立的沙箱.一个沙箱中的对象无法与另一个沙箱中的对象进行交互.最常见的表现是StringVar在一个解释器中创建的在另一个解释器中不可见.小部件也是如此 - 您无法在一个解释器中创建小部件,该解释器在另一个解释器中具有父小部件.

从技术角度来看,没有理由不能同时拥有两个实例Tk.反对它的建议是因为很少有实际需要有两个或更多不同的Tcl解释器,并且它会导致初学者难以掌握的问题.

第二个片段是否被认为更好一点,或者它是否受到与第一个代码相同条件的影响?

如果不知道你想要实现的目标,问题中的第二个例子是否更好是不可能的.它可能并不好,因为再次,你真的需要两个实例的时间很少.

最佳解决方案99.9%的时间是创建一个Tk用于程序生命周期的实例.很简单,这就是tkinter和底层Tcl/Tk解释器的设计使用方式.

  • 如果您将要有多个`Tk`实例,它们应该放在不同的线程中,以便它们获得自己的事件处理循环.技术上可以将这些线程中的底层小部件融合到一个视图中,但这是一种非常先进的技术,我不知道它是否实际暴露在Tkinter中.坦率地说,在实践中将所有GUI活动保持在单个线程中要简单得多. (2认同)

The*_*ard 9

我不同意tkinter社区不鼓励使用多个tk.Tk窗口的观点。您可以有多个tk.Tk窗口。使用多个实例tk.Tk是创建真正彼此独立的窗口的唯一方法。大多数人在创建多个窗口时犯的唯一错误是他们在创建s/ s/ s/...时tk.Tk忘记传入。master=...PhotoImageStringVarIntVar

例如看看这段代码:

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()
Run Code Online (Sandbox Code Playgroud)

上面的代码不起作用。如果您添加master=root2tk.StringVar(),那么它将完美地工作。这是因为存储了intkinter的第一个实例。那么如果你不传入,它会假设你想要传入 的窗口。tk.Tk()tk._default_rootmaster=...tk._default_root


.mainloop()人们犯的另一个错误是应该调用多少次。它处理来自所有tk.Tk活动窗口的事件,因此您只需要一个.mainloop()

对于不同意的人,我会对一个实际问题是由多个tk.Tk窗口引起的示例感兴趣。


Rol*_*ith 5

到目前为止,我找到的最好的参考是tkinterbook 中的这一部分

在我们到目前为止使用的简单示例中,屏幕上只有一个窗口;根窗口。这是在调用Tk构造函数时自动创建的

如果您需要创建额外的窗口,您可以使用Toplevel小部件。它只是在屏幕上创建一个新窗口,该窗口的外观和行为与原始根窗口非常相似

我的看法是,一个Tk实例创建了一个Toplevel小部件,加上诸如 之类的东西mainloop,其中应该只有一个。