在Tkinter应用程序中是否继承Frame

foo*_*ion 28 python tkinter

我已经看到了两种设置tkinter程序的基本方法.有没有理由更喜欢一个到另一个?

from Tkinter import *

class Application():
    def __init__(self, root, title):
        self.root = root
        self.root.title(title) 

        self.label = Label(self.root, text='Hello')
        self.label.grid(row=0, column=0)  

root = Tk()
app = Application(root, 'Sample App')
root.mainloop()
Run Code Online (Sandbox Code Playgroud)

from Tkinter import *

class Application(Frame):
    def __init__(self, title, master=None):
        Frame.__init__(self, master)
        self.grid()
        self.master.title(title) 

        self.label = Label(self, text='Hello')
        self.label.grid(row=0, column=0) 

app = Application('Sample App')
app.mainloop()   
Run Code Online (Sandbox Code Playgroud)

Bry*_*ley 26

我更喜欢*的选项是继承Tk类.我认为这是更合理的选择,因为窗口实际上是您的应用程序.来自继承,Frame没有任何我更有意义,然后继承ButtonCanvasLabel.由于您只能拥有一个根,因此您继承的是有意义的.

我还认为如果你进行导入import Tkinter as tk而不是代码,它会使代码更具可读性from Tkinter import *.然后你的所有电话都明确提到了这个tk模块.我不建议所有模块都使用它,但对我来说这对Tkinter来说很有意义.

例如:

import Tkinter as tk

class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.label = tk.Label(text="Hello, world")
        self.label.pack(padx=10, pady=10)

app = SampleApp()
app.mainloop()
Run Code Online (Sandbox Code Playgroud)

*注意:自从写这个答案以来我改变了我的立场.我现在更愿意继承Frame而不是继承Tk.这种方式没有真正的优势,它更像是一种哲学选择而不是其他任何东西.无论如何,我相信无论你是继承Frame还是继承Tk,我认为任何一种选择都比代码中的第一个继承任何东西的例子更好.

在一个微弱的优势继承Frame拥有Tk在您希望您的应用程序支持多窗口相同的情况.在这种情况下,继承Frame允许您创建第一个窗口作为root的子项,并将其他窗口作为实例的子项创建Toplevel.但是,我发现很少有程序需要这样做.

有关我认为Tkinter程序应该如何构建的更多信息,请参阅Python Tkinter程序结构问题的回答.


unu*_*tbu 12

Frame通常用作其他小部件几何主控.由于应用程序通常具有多个小部件,因此您通常希望将它们全部包含在Frame中,或者至少使用Frame来添加一些borderwidth,填充或其他精确的小部件.

您可能在网络上找到的许多示例代码段都不使用Frame,因为他们只想在最短的代码中演示某些功能.

因此,如果需要,请使用Frame,否则不要.

编辑:我认为在这个Tkinter教程中给出了组织GUI的最佳方法:

simpleApp.py:

import Tkinter as tk

class SimpleApp(object):
    def __init__(self, master, **kwargs):
        title=kwargs.pop('title')
        frame=tk.Frame(master, **kwargs)
        frame.pack()
        self.label = tk.Label(frame, text=title)
        self.label.pack(padx=10,pady=10)

if __name__=='__main__':
    root = tk.Tk()
    app = SimpleApp(root,title='Hello, world')
    root.mainloop()
Run Code Online (Sandbox Code Playgroud)

这主要是你继承的第一个例子,而不是.我认为这比子类更好,因为我们没有覆盖任何方法.我宁愿把它想象成一个而不是一个.SimpleAppobjectFrameFrameFrameSimpleAppFrameFrame

有了SimpleApp子类object确实比子类有明显的优势tk.Tk,但是:它可以很容易地嵌入SimpleApp到更大的应用程序中:

import simpleApp
import Tkinter as tk

class BigApp(object):
    def __init__(self, master, **kwargs):
        title=kwargs.pop('title')
        frame=tk.Frame(master, **kwargs)
        frame.pack()
        self.simple = simpleApp.SimpleApp(frame,title=title)
        frame.pack(padx=10, pady=10)
        self.simple2 = simpleApp.SimpleApp(frame,title=title)    
        frame.pack()

if __name__=='__main__':
    root = tk.Tk()
    app = BigApp(root,title='Hello, world')
    root.mainloop()
Run Code Online (Sandbox Code Playgroud)

因此,simpleApp.py可以是独立脚本以及可导入模块.如果你尝试SimpleApp继承tk.Tk,你会得到额外的不受欢迎的窗口.