调用Tk()实际上做了什么?

时间:2014-07-14 03:26:35

标签: python tkinter tk

当我查看NMT Tkinter 8.5 Reference中的一个最小例子时,我正在刷Tkinter。

#!/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's Library Referenceeffbot.orgTkDocs),通常会调用root = tk.Tk(),其余的示例都是基于此构建的。我也没有在NMT的参考文献中看到Tk类初始化的任何类型的引用。

我可以得到的有关Tk类的信息也很模糊,Python Reference仅将其列为“顶级窗口小部件......通常是应用程序的主窗口”。最后,如果我替换前面介绍的片段中的最后几行:

root = tk.Tk()
app = Application(root)

该程序将像以前一样运行。考虑到所有这些,我有兴趣知道的是:

  • 调用root = tk.Tk()实际上做了什么(例如,初始化的内容)以及为什么之前的代码段可以在没有它的情况下工作?
  • 如果我不打电话给Tk()而只是围绕Frame课程构建我的应用程序,我会遇到任何陷阱或限制吗?

3 个答案:

答案 0 :(得分:12)

Tkinter通过在封面下启动tcl / tk解释器,然后将tkinter命令转换为tcl / tk命令来工作。主窗口和此解释器是内在链接的,两者都是tkinter应用程序工作所必需的。

创建Tk的实例初始化此解释器并创建根窗口。如果您没有显式初始化它,则在创建第一个窗口小部件时将隐式创建一个。

我不认为自己没有初始化会有任何陷阱,但作为蟒蛇状态的禅,"显性优于隐含"。如果您明确创建Tk的实例,您的代码将更容易理解。例如,它会阻止其他人询问您刚才询问有关此其他代码的代码的相同问题。

答案 1 :(得分:3)

Bryan Oakley's回答是现场。创建窗口小部件将隐式创建tcl / tk解释器的实例。但是,我想添加一些代码片段,以便更好地理解Tk是如何隐式创建的。

每当创建一个Widget对象时(无论是Frame还是Button,甚至是基于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都是全局变量,在__init__.py包中的tkinter文件的第132-133行中声明。它们初始化为以下值:

_support_default_root = 1
_default_root = None

这意味着,如果未提供master,并且尚未创建解释器,则会创建Tk的实例并将其指定为所有人的默认根目录未来的小部件。

创建Tk类的实例时,还有一些有趣的事情。以下代码段来自Tk._loadtk方法:

if _support_default_root and not _default_root:
    _default_root = self

这意味着,无论Tk类如何初始化,它总是被设置为默认根。

答案 2 :(得分:-4)

有时,某些小部件会自行运行Tk()。但我不知道哪些小部件和原因。

即使您不使用mainloop(),有时也会运行 - 主要是在Windows上。

Tkinter是Tcl / Tk的奇怪包装:)

但我更喜欢始终使用root = Tk()root.mainloop()