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
What does calling Tk() actually do?
提问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 Tk
class 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 Tk
class initialization anywhere on the NMT's reference.
一切都很好,直到我注意到Tk
该类没有被初始化。在我可以找到的其他在线参考资料(Python 的库参考、effbot.org、TkDocs)中,通常会调用root = tk.Tk()
,其余示例均基于该调用构建。我也没有Tk
在 NMT 参考的任何地方看到任何对类初始化的参考。
The information I could get regarding the Tk
class 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 theFrame
class?
- 调用
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 Tk
initializes 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 BaseWidget
class' __init__
method is called, which in turn calls the _setup
method. 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_root
and _default_root
are global variables, declared in lines 132-133 of the __init__.py
file in the tkinter
package. 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 master
isn't provided, and if an interpreter wasn't already created, an instance of Tk
gets created and assigned as the default root for all future widgets.
这意味着,如果master
未提供,并且尚未创建解释器,则会创建一个实例Tk
并将其分配为所有未来小部件的默认根。
There is also something interesting when creating an instance of the Tk
class. The following snippet comes from the Tk._loadtk
method:
创建Tk
类的实例时还有一些有趣的事情。以下代码段来自该Tk._loadtk
方法:
if _support_default_root and not _default_root:
_default_root = self
Which means that, regardless of how the Tk
class gets initialized, it is always set up as the default root.
这意味着,无论Tk
类如何初始化,它始终设置为默认根。