Python:Tkinter:为什么是 root.mainloop() 而不是 app.mainloop() [英] Python: Tkinter: Why is it root.mainloop() and not app.mainloop()

查看:221
本文介绍了Python:Tkinter:为什么是 root.mainloop() 而不是 app.mainloop()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Stack Overflow 的新成员.我找到了这个线程,但不允许对其发表评论或提问,所以我想我只是在这里引用它:如何在 Python 的 Tkinter 中制作交互式列表,并带有可以编辑这些列表的按钮?

I'm a new member to Stack Overflow. I found this thread, but was not allowed to comment or ask questions on it, so I thought I'd just reference it here: How can I make a in interactive list in Python's Tkinter complete with buttons that can edit those listings?

from tkinter import *
import os
import easygui as eg

class App:

    def __init__(self, master):
        frame = Frame(master)
        frame.pack()

        # character box
        Label(frame, text = "Characters Editor").grid(row = 0, column = 0, rowspan = 1, columnspan = 2)
        charbox = Listbox(frame)
        for chars in []:
            charbox.insert(END, chars)
        charbox.grid(row = 1, column = 0, rowspan = 5)
        charadd = Button(frame, text = "   Add   ", command = self.addchar).grid(row = 1, column = 1)
        charremove = Button(frame, text = "Remove", command = self.removechar).grid(row = 2, column = 1)
        charedit = Button(frame, text = "    Edit    ", command = self.editchar).grid(row = 3, column = 1)

    def addchar(self):
        print("not implemented yet")
    def removechar(self):
        print("not implemented yet")
    def editchar(self):
        print("not implemented yet")


root = Tk()
root.wm_title("IA Development Kit")
app = App(root)
root.mainloop()

有人可以向我解释为什么最后一行是 root.mainloop() 吗?作为 Python 的新手,并且来自面向过程且没有面向对象经验的背景,我本以为它会是 app.mainloop().

Could somebody explain to me why the very last line is root.mainloop()? Being a novice with Python, and coming from a background that's procedural-oriented with no object-orient experience, I would have thought it would have been app.mainloop().

实际上 app = App(root) ,在其余代码中再也不会使用 app 了!我无法理解为什么 root.mainloop() 仍然有效.

In fact app = App(root) , app is never used again in the rest of the code! I'm having trouble understanding why root.mainloop() still works.

推荐答案

我不确定你是否会觉得这个答案令人满意,但是你调用 root.mainloop() 因为 root 是具有 mainloop 方法的对象.在您提供的代码中,App 没有 mainloop 函数.

I'm not sure if you'll find this answer satisfying, but you call root.mainloop() because root is the object that has the mainloop method. In the code you've given, App has no mainloop function.

简单来说,这就是 tkinter 的工作方式——你总是通过调用根窗口的 mainloop 方法来结束你的脚本.当该方法返回时,您的程序将退出.

In simpler terms, this is just how tkinter works -- you always end your script by calling the mainloop method of the root window. When that method returns, your program will exit.

让我们从头开始.最简单的非 OO Tkinter 程序将类似于以下示例.请注意,这是一个 python 2.x 示例,我不使用全局导入,因为我认为全局导入不好.

Let's start at the beginning. The simplest, non-OO Tkinter program is going to look like the following example. Note that this is a python 2.x example, and I do not use a global import since I think global imports are bad.

import Tkinter as tk
root = tk.Tk()
<your widgets go here>
root.mainloop()

许多人发现纯过程风格不是编写代码的有效方式,因此他们可能会选择以面向对象的风格编写代码.将应用程序"视为单例对象是很自然的.有很多方法可以做到这一点 - 不幸的是,您问题中的方法不是更清晰的方法之一.

Many people find that a pure procedural style is not an effective way to write code, so they might choose to write this in an object-oriented style. It's natural to think of "the app" as a singleton object. There are many ways to do this -- the one in your question is, unfortunately, not one of the clearer ways to do it.

IMO 稍微好一点的方法是将代码结构如下:

A slightly better way, IMO, would be to structure the code like this:

class App(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        <your widgets go here>
app = App()
app.mainloop()

在这种情况下,mainloop 仍在被调用,尽管现在它是 App 的方法,因为 App 继承自 Tk.它在概念上与 root.mainloop() 相同,因为在这种情况下,app 根窗口,即使它具有不同的名称.

In this case, mainloop is still being called, though now it's a method of App since App inherits from Tk. It is conceptually the same as root.mainloop() since in this case, app is the root window even though it goes by a different name.

所以,在这两种情况下,mainloop 都是属于根窗口的方法.在这两种情况下,必须调用 GUI 才能正常运行.

So, in both cases, mainloop is a method that belongs to the root window. And in both cases, it must be called for the GUI to function properly.

还有第三种变体,它是您选择的代码所使用的.有了这种变化,有几种方法可以实现它.变化是您的问题使用一个类来定义 GUI,但不是继承自 Tk.这完全没问题,但您仍然必须在某个时候调用 mainloop.由于您没有在类中创建(或继承)mainloop 函数,因此您必须调用与根窗口关联的函数.我所说的变化是将 App 的实例添加到根窗口的方式和位置,以及最终调用 mainloop 的方式.

There is a third variation which is what the code you picked is using. And with this variation, there are several ways to implement it. The variation is your question uses a class to define the GUI, but does not inherit from Tk. This is perfectly fine, but you still must call mainloop at some point. Since you don't create (or inherit) a mainloop function in your class, you must call the one associated with the root window. The variations I speak of are how and where the instance of App is added to the root window, and how mainloop is ultimately called.

就我个人而言,我更喜欢 App 继承自 Frame,并且您将应用程序打包外部应用程序的定义.我使用的模板如下所示:

Personally I prefer that App inherits from Frame, and that you pack the app outside the definition of the app. The template I use looks like this:

class App(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        <your widgets go here>

if __name__ == "__main__":
    root = tk.Tk()
    app = App(root)
    app.pack(fill="both", expand=True)
    root.mainloop()

在最后一个示例中,approot 是两个完全不同的对象.app 表示存在于根窗口 的框架.框架通常以这种方式使用,作为其他小部件组的容器.

In this final example, app and root are two completely different objects. app represents a frame that exists inside the root window. Frames are commonly used this way, as a container for groups of other widgets.

因此,在所有情况下,都必须调用 mainloop.在哪里调用它,以及如何调用,这在一定程度上取决于您的编码风格.有些人喜欢从根窗口继承,有些人不喜欢.无论哪种情况,您都必须调用根窗口的 mainloop 函数.

So, in all cases, mainloop must be called. where it is called, and how, depends a bit on your coding style. Some people prefer to inherit from the root window, some don't. In either case, you must call the mainloop function of the root window.

这篇关于Python:Tkinter:为什么是 root.mainloop() 而不是 app.mainloop()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆