Python 调用 Tk() 实际上有什么作用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24729119/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 05:05:42  来源:igfitidea点击:

What does calling Tk() actually do?

pythontkintertk

提问by Doktoro Reichard

I was brushing up on Tkinter when I looked upon a minimal example from the NMT Tkinter 8.5 Reference.

当我查看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()

It's all well and good, until I notice that the Tkclass isn't being initialized. In other online reference material I could find (Python's Library Reference, effbot.org, TkDocs), there's usually a call to root = tk.Tk(), from which the rest of the examples are built upon. I also didn't see any sort of reference to the Tkclass initialization anywhere on the NMT's reference.

一切都很好,直到我注意到Tk该类没有被初始化。在我可以找到的其他在线参考资料(Python 的库参考effbot.orgTkDocs)中,通常会调用root = tk.Tk(),其余示例均基于该调用构建。我也没有Tk在 NMT 参考的任何地方看到任何对类初始化的参考。

The information I could get regarding the Tkclass is also vague, with the Python Reference only listing it as a "toplevel widget ... which usually is the main window of an application". Lastly, if I replace the last lines in the snippet I presented earlier:

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

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

The program would run as well as it did before. With all this in mind, what I'm interested in knowing is:

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

  • What does calling root = tk.Tk()actually do (as in, what gets initialized) and why can the previous snippet work without it?
  • Would I run into any pitfalls or limitations if I don't call Tk()and just built my application around the Frameclass?
  • 调用root = tk.Tk()实际上做了什么(例如,什么被初始化了),为什么前面的代码片段没有它也能工作?
  • 如果我不打电话Tk()而只是围绕Frame课程构建我的应用程序,我会遇到任何陷阱或限制吗?

采纳答案by Bryan Oakley

Tkinter works by starting a tcl/tk interpreter under the covers, and then translating tkinter commands into tcl/tk commands. The main window and this interpreter are intrinsically linked, and both are required for a tkinter application to work.

Tkinter 的工作原理是在幕后启动 tcl/tk 解释器,然后将 tkinter 命令转换为 tcl/tk 命令。主窗口和这个解释器有着内在的联系,两者都是 tkinter 应用程序工作所必需的。

Creating an instance of Tkinitializes this interpreter and creates the root window. If you don't explicitly initialize it, one will be implicitly created when you create your first widget.

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

I don't think there are any pitfalls by not initializing it yourself, but as the zen of python states, "explicit is better than implicit". Your code will be slightly easier to understand if you explicitly create the instance of Tk. It will, for instance, prevent other people from asking the same question about your code that you just asked about this other code.

我认为不自己初始化不会有任何陷阱,但正如 Python 的禅宗所说,“显式优于隐式”。如果您显式地创建Tk. 例如,它会阻止其他人就您的代码提出与您刚刚询问其他代码相同的问题。

回答by furas

Sometimes some widgets run Tk()on their own. But I don't know which widgets and why.

有时,一些小部件会Tk()自行运行。但我不知道哪些小部件以及为什么。

Sometimes it runs even if you don't use mainloop()- mostly on Windows.

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

Tkinter is strange wrapper on Tcl/Tk :)

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

But I prefer to use root = Tk()and root.mainloop()always.

但我更喜欢使用root = Tk()root.mainloop()总是。

回答by Doktoro Reichard

Bryan Oakley'sanswer is spot on. Creating a widget will implicitlycreate an instance of the tcl/tk interpreter. I would, however, like to add some pieces of code, to better understand how Tk is implicitly created.

布莱恩奥克利的答案是正确的。创建小部件将隐式创建 tcl/tk 解释器的实例。然而,我想添加一些代码,以更好地理解 Tk 是如何隐式创建的。

Whenever a Widget object is created (whether it is a Frame or a Button or even a ttk-based widget), the BaseWidgetclass' __init__method is called, which in turn calls the _setupmethod. Here is a snippet of the relevant part:

每当创建 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

Both _support_default_rootand _default_rootare global variables, declared in lines 132-133 of the __init__.pyfile in the tkinterpackage. They are initialized to the following values:

这两个_support_default_root_default_root是全局变量,在线条的132-133宣布__init__.py在文件tkinter包。它们被初始化为以下值:

_support_default_root = 1
_default_root = None

This means that, if masterisn't provided, and if an interpreter wasn't already created, an instance of Tkgets created and assigned as the default root for all future widgets.

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

There is also something interesting when creating an instance of the Tkclass. The following snippet comes from the Tk._loadtkmethod:

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

if _support_default_root and not _default_root:
    _default_root = self

Which means that, regardless of how the Tkclass gets initialized, it is always set up as the default root.

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