Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
131 views
in Technique[技术] by (71.8m points)

python 3.x - Tkinter application crashing, while clicking different buttons

My application after few random clicks on the buttons starts slowing down drastically and sometimes the labels and buttons disappear completely and the GUI freezes (except the "X" button, it just destroys the program, which is intentional).

My guess would be that the way I want to clear the window (my clear(self) function) is not the proper way to clear it, since I want the buttons to stay no matter which button you click, everything below them should be cleared. Or maybe it is my class structure, I have seen tons of other ways to create a tkinter class..., maybe I am missing out on a core thing in my code?

My code so far:

from tkinter import *


class LearnTkinter:
    def __init__(self, top):
        self.top = top
        self.title = top.title("LearnTkinter")
        self.configure = top.configure(bg="#d9d9d9", highlightbackground="grey", highlightcolor="darkgrey")

        wWidth = top.winfo_reqwidth()
        wHeight = top.winfo_reqheight()

        x = int(top.winfo_screenwidth() / 2 - (wWidth / 2))
        y = int(top.winfo_screenheight() / 3 - (wHeight / 2))

        top.geometry(f"+{x}+{y}")
        top.minsize(274,520)

        self.Kill = Button(top,text="X",bg="#d9d9d9", command = top.destroy).place(height=54,width=72)
        self.Infos = Button(top, text="i", bg="#d9d9d9", command=self.info_w).place(relx=0.25,height=54,width=72)
        self.Help = Button(top, text="?", bg="#d9d9d9", command=self.help_w).place(relx=0.5,height=54,width=72)
        self.Settings = Button(top, text="O", bg="#d9d9d9", command=self.settings_w).place(relx=0.75,height=54,width=72)

        self.Frame1 = Frame(top, bg="black", relief="groove", borderwidth="8").place(rely=0.1,relheight=0.202,relwidth=1.004)

    def clear(self):
        for widget in top.winfo_children():
            widget.destroy()

            Button(top,text="X", bg="#d9d9d9", command=top.destroy).place(height=54,width=72)
            Button(top, text="i", bg="#d9d9d9", command=self.info_w).place(relx=0.25,height=54,width=72)
            Button(top, text="?", bg="#d9d9d9", command=self.help_w).place(relx=0.5,height=54,width=72)
            Button(top, text="O", bg="#d9d9d9", command=self.settings_w).place(relx=0.75,height=54,width=72)

    def info_w(self):
        self.clear()
        top.title("Info")
        Label(top, text="This is going to be the information section ", bg="grey").place(rely=0.1, relwidth=1)

    def help_w(self):
        self.clear()
        top.title("Help")
        Label(top, text="This is going to be the help center", bg="grey").place(rely=0.1, relwidth=1)

    def settings_w(self):
        self.clear()
        top.title("Settings")



top = Tk()
exa_gui = LearnTkinter(top)
top.mainloop()
question from:https://stackoverflow.com/questions/65861785/tkinter-application-crashing-while-clicking-different-buttons

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your problem was that you were creating in the clear function 4 new buttons each iteration.

  • For example: if you had at the start 5 widgets (4 buttons + 1 frame). After the first call of clear function you created 5 * 4 new buttons! And the second time you called the function button you created 5 * 4 * 4 new buttons. Which is 80 new widgets in the GUI. After the 4rd call you had already 1280 new buttons!
  • You can imagine that it was too much widgets and the GUI would just froze up.

So if you move the creation of the buttons before or after the for loop (not during!) it will make your lag go away:

def clear(self):
    for widget in self.top.winfo_children():
        widget.destroy()

    Button(self.top, text="X", bg="#d9d9d9", command=self.top.destroy).place(height=54,width=72)
    Button(self.top, text="i", bg="#d9d9d9", command=self.info_w).place(relx=0.25,height=54,width=72)
    Button(self.top, text="?", bg="#d9d9d9", command=self.help_w).place(relx=0.5,height=54,width=72)
    Button(self.top, text="O", bg="#d9d9d9", command=self.settings_w).place(relx=0.75,height=54,width=72)

Also one additional thing:

  • In all your methods of the LearnTkinter class you are referring to the top variable.
  • But when you are calling this variable you are not using the prefix self.top but simply top.
  • Change this in all your functions / methods.
  • It only works because you also (by chance) named top variable in the program.

The top variable:

top = Tk() #You are referring in you 'LearnTkinter' class to this variable. Not the one 'inside' the class.
exa_gui = LearnTkinter(top)
top.mainloop()

I know that in python you are actually pointing to the same object. But the reason this works is the same name. Try changing it and you will see it wont work.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...