【问题标题】:Tkinter application crashing, while clicking different buttonsTkinter 应用程序崩溃,同时单击不同的按钮
【发布时间】:2021-01-23 16:46:31
【问题描述】:

我的应用程序在几次随机点击按钮后开始显着变慢,有时标签和按钮完全消失,GUI 冻结(“X”按钮除外,它只是破坏程序,这是故意的)。

我的猜测是我想要清除窗口的方式(我的 clear(self) 函数)不是清除它的正确方法,因为无论您单击哪个按钮,它们下方的所有内容都希望按钮保持不变应该清除。 或者可能是我的类结构,我已经看到了很多其他方法来创建一个 tkinter 类...,也许我错过了我的代码中的核心内容?

到目前为止我的代码:

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()

【问题讨论】:

    标签: python-3.x tkinter button


    【解决方案1】:

    您的问题是您在每次迭代时都在 clear 函数 4 中创建新按钮。

    • 例如:如果您一开始有 5 个小部件(4 个按钮 + 1 个框架)。 在第一次调用 clear 函数后,您创建了 5 * 4 new 纽扣!第二次调用功能按钮时 创建了5 * 4 * 4 新按钮。这是80 GUI 中的新小部件。 在第 4 次通话后,您已经有了 1280 新按钮!
    • 您可以想象,小部件过多,GUI 就会冻结。

    因此,如果您在 for loop 之前或之后移动按钮的创建(而不是在期间!),它将消除您的延迟:

    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)
    

    还有一件事:

    • LearnTkinter 类的所有方法中,您指的是top 变量。
    • 但是当你调用这个变量时,你没有使用前缀self.top,而只是使用top
    • 在您的所有函数/方法中更改此项。
    • 它之所以有效,是因为您还(偶然)在程序中命名了 top 变量。

    top 变量:

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

    我知道在 python 中你实际上指向的是同一个对象。但是这个工作的原因是同一个名字。尝试更改它,您会发现它不起作用。

    【讨论】:

    • 是一个愚蠢的错误.. 但是谢谢你的欢迎
    • 这很正常,任何人都可能发生!我还在答案中为您写了其他内容。查看top 变量:)
    • 我想弄清楚,我得到 Nonetype 错误,对象不可调用
    • 不要在self.top = top这一行的__init__()方法中使用它。这条线很好。
    • 我重写了每个方法/函数,还有一种方法可以不重新创建保留的按钮(在 clear 函数中),例如我不能只调用 self.Kill() 而不是创建新的“按钮(self.top....)”
    猜你喜欢
    • 1970-01-01
    • 2014-07-24
    • 2017-07-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多