简体   繁体   English

在tkinter中制作窗口的哪种方式更好?

[英]Which way of making a window in tkinter is better?

I have seen two different tutorials on making a basic window using Tkinter. 我已经看过两个使用Tkinter制作基本窗口的不同教程。 One of the tutorials uses a class with functions to initialize and assemble the window. 其中一个教程使用带有函数的类来初始化和组装窗口。 In the other tutorial, they just made a window without using classes or functions. 在另一个教程中,他们只是在不使用类或函数的情况下创建了一个窗口。

Just to be clear, I'm NOT talking about what the windows do per se . 为了清楚起见,我不是在谈论窗户本身所做的事情。 I'm just wondering which method is better to implement Tkinter. 我只是想知道哪种方法更适合实现Tkinter。

Here's the code for both if that explanation doesn't make sense. 如果这个解释没有意义,这是两者的代码。

Here's the code for both if that explanation doesn't make sense. 如果这个解释没有意义,这是两者的代码。

CODE #1 uses classes 代码#1使用类

from tkinter import *

class Window(Frame):

    def __init__(self, master=NONE):

        Frame.__init__(self, master)
        self.master = master

        self.init_window()

    def init_window(self):

        self.master.title("GUI")  #

        self.pack(fill = BOTH, expand=1)

        # We created a button below to see how to do it but commented it out for now.
        '''closeButton = Button(self, text='Close', command=self.client_exit)  # Making a new button called closeButton.

        closeButton.place(x=0, y=0)  # Places the button at given co-ordinates. (0,0) is top left. This isn't cartesian.'''

        menuBar = Menu(self.master)
        self.master.config(menu=menuBar)

        file = Menu(menuBar)
        file.add_command(label = 'Exit', command = self.client_exit)
        menuBar.add_cascade(label = 'File', menu=file)

        edit = Menu(menuBar)
        edit.add_command(label = 'Show Image', command = self.showImg)
        edit.add_command(label = 'Show Text', command = self.showTxt)
        menuBar.add_cascade(label = 'Edit', menu=edit)

    def showImg(self):
        load = Image.open('CatPic.jpg')
        render = ImageTk.PhotoImage(load)
        catImage = Label(self, image=render)
        catImage.image = render
        catImage.place(x=250, y=250)

    def showTxt(self):
        writeText = Label(self, text = "Hi I'm Temmie")
        writeText.pack()



root = Tk()  # Tk() is a function within Tkinter. 'root' is the name of our Frame.
root.geometry("500x500")  # Defines size of 'root'.
root.mainloop()

app = Window(root)  # Finally, we use the Window class to make a window under the name 'app'.

CODE #2 uses no such concept 代码#2没有使用这样的概念

from tkinter import *
root=Tk()


topFrame = Frame(root)
topFrame.pack()
bottomFrame = Frame(root)
bottomFrame.pack(side=BOTTOM)

button1=Button(topFrame, text="Button 1", fg="red") #fg foreground is optional
button2=Button(topFrame, text="Button 2", fg="blue") #fg is optional
button3=Button(topFrame, text="Button 3", fg="green") #fg is optional
button4=Button(bottomFrame, text="Button 4", fg="black") #fg is optional

button1.pack(side=LEFT,fill=X)
button2.pack(side=LEFT)
button3.pack(side=LEFT)
button4.pack(side=BOTTOM)

root.mainloop()

It depends only on you. 这取决于你。


For small examples I use mostly only functions - it is faster to write. 对于小例子,我主要使用的只是函数 - 写入速度更快。
And beginners will understand it - they mostly don't know classes. 初学者会理解它 - 他们大多不懂课。

For something bigger I use classes - it makes code cleaner for me. 对于更大的东西,我使用类 - 它使代码更清洁。

But I do this way not only in Tkinter but also in other modules - like PyGame. 但我这样做不仅在Tkinter中,而且在其他模块中 - 比如PyGame。

Both pieces of code are doing basically the same stuff under the hood. 这两段代码基本上都在做同样的事情。 The first piece takes the Frame as a base class and extends it with the default parameters and methods so that it can be used multiple times for a window that you like. 第一部分将Frame作为基类,并使用默认参数和方法对其进行扩展,以便可以对您喜欢的窗口多次使用它。 So the first piece of code is how a normal OOP project would use tKinter so that one can basically modify everything and plug their own code whereever they feel that tKinter is lacking or misguided. 所以第一段代码就是普通的OOP项目如何使用tKinter,以便人们可以基本上修改所有内容并插入自己的代码,只要他们觉得tKinter缺乏或误导。 At the same time all the modifications are easily usable for other projects (or other windows) and if you start working on another project that has all the same prerequisites, then you can just take your Window class and get cracking. 同时,所有修改都可以轻松地用于其他项目(或其他窗口),如果您开始处理具有所有相同先决条件的另一个项目,那么您可以使用Window类并开始破解。

On the other hand the simpler solution takes advantage of all that tTkinter offers out of the box which means you can generate lots of customizable content with a few lines of code, using all tKinter settings, parameters and so on. 另一方面,更简单的解决方案利用了tTkinter开箱即用的所有功能,这意味着您可以使用所有tKinter设置,参数等,使用几行代码生成大量可自定义的内容。 The second solution is not so easily reusable and if you want certain parts of it, you can't just take the whole class definition, but have to pick out the lines that modify your window. 第二种解决方案不是那么容易重复使用,如果你想要它的某些部分,你不能只采用整个类定义,而是必须选择修改窗口的行。 Also when you get into a situation where you have to override tKinter stuff, you need to create your own Window class anyways. 此外,当您遇到必须覆盖tKinter的情况时,您还需要创建自己的Window类。 But then again, in most simpler projects that doesn't happen (I've written to projects using tKinter, both of them about 1500 lines, and neither of them required overriding the Frame class). 但话说回来,在大多数更简单的项目中都没有发生(我已经使用tKinter编写了项目,它们都有大约1500行,而且它们都不需要覆盖Frame类)。

So TL;DR: 所以TL; DR:
If you're an experienced OOP developer that has used all kinds of frameworks etc. beforehand, I would go for the first solution that overrides the Frame class. 如果您是一位经验丰富的OOP开发人员,事先已经使用过各种框架等,那么我会选择第一个覆盖Frame类的解决方案。
If - as it seems from the question - you're a beginner who wants to get going and see a result instead of hassling with OOP quirks and other arguably unnecessary stuff for a simple project, I'd go for the second and lighter version. 如果 - 从问题看起来 - 你是一个想要开始并看到结果的初学者而不是为了一个简单的项目而烦恼OOP怪癖和其他可能不必要的东西,我会选择第二个更轻的版本。

PS! PS! One should never use from somepackage import * because of name clashes, tracking imports in files and so on. 永远不要使用from somepackage import *因为名称冲突,跟踪文件中的导入等等。 Instead it is recommended to use just import tkinter and then you can access all of tKinter's stuff as tkinter.Frame , tkinter.Button etc. Also a good way is to import tKinter as import tkinter as tk , then you can use it as tk.Frame , tk.Button etc and all in all you have to write less. 相反,建议只使用import tkinter tkinter,然后你可以访问tkinter.Frametkinter.Button等所有tKinter的东西。另外一个好方法是将tKinter import tkinter as tk import tkinter,然后你可以将它用作tk.Frametk.Button等等所有你必须少写。 If you only want to use, say one or two components from a package, then you'd usually import them as from tkinter import Button, Frame and then use them just as Button and Frame . 如果你只想使用一个包中的一个或两个组件,那么你通常会from tkinter import Button, Frame导入它们,然后将它们用作ButtonFrame Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM