为什么每次单击按钮时,tkinter GUI都会闪烁?

时间:2020-07-20 15:02:55

标签: python button tkinter

我创建了一个简单的GUI,但是每次单击其中一个按钮时,GUI都会闪烁。我看了其他一些SO问题,但没有一个抽象的问题足以帮助我解决自己的特殊问题。

这是我正在使用的代码(我知道这是很多代码,但是我认为任何小细节都可能是问题的原因):

import tkinter as tk

class LeftMenu:

    def __init__(self, master):

        def call_home():
            h = Home(master)
            h.__init__(master)

        def call_overviews():
            h = Overviews(master)
            h.__init__(master)

        self.maincolor = 'darkgrey'
        self.menucolor = 'grey'

        # Menu creation
        menu = tk.Frame(master, bg=self.menucolor)

        # def quitcurrent():
        #     menu.quit()

        # Menu positioning
        menu.grid(row=0, column=0, sticky='nsew')
        # Menu items
        self.home = tk.Button(menu, text='Home', command=lambda: [call_home()])
        self.overview = tk.Button(menu, text='Overview', command=lambda: [call_overviews()])


        # Menu items location
        self.home.grid(row=0, column=0, pady=(25, 50), padx=15)
        self.overview.grid(row=1, column=0, pady=(0, 50), padx=15)


        # Menu items configuration
        buttons = [self.home, self.overview]
        for self.button in buttons:
            self.button.configure(width=20, height=5, highlightbackground=self.menucolor)



class Home(LeftMenu):

    def __init__(self, master):
        super().__init__(master)

        self.homeright(master)


    def homeright(self, master):
        # Main creation
        main = tk.Frame(master, bg=self.maincolor)

        # Main positioning
        main.grid(row=0, column=1, sticky='nsew')

        # Main items
        self.maintext = tk.Label(main, text='Welcome to the Apartment Manager', bg=self.maincolor, pady=250)
        self.maintext.pack()


class Overviews(LeftMenu):

    def __init__(self, master):
        super().__init__(master)

        self.homeright(master)

    def homeright(self, master):
        # Main creation
        main = tk.Frame(master, bg=self.maincolor)

        # Main positioning
        main.grid(row=0, column=1, sticky='nsew')

        # Main items
        self.maintext = tk.Label(main, text='It actually worked', bg=self.maincolor, pady=250)
        self.maintext.pack()


root = tk.Tk()
root.title('Apartment Manager')
root.geometry('750x750')
root.grid_columnconfigure(0, weight=1)
root.grid_columnconfigure(1, weight=7)
root.grid_rowconfigure(0, weight=1)
root.wm_withdraw()
root.update()

runit = Home(root)

root.after(1, root.deiconify)
root.mainloop()

我认为这可能与行有关:

root.wm_withdraw()
root.update()
root.after(1, root.deiconify)

所以我在没有这些行的情况下运行了它,但是没有任何效果。有人知道我每次单击其中一个按钮时导致GUI闪烁的原因以及如何解决吗?

使用Python 3.8和tkinter 8.6

1 个答案:

答案 0 :(得分:2)

我至少看到两个问题。首先,当我单击一个按钮时,它将为右侧创建一组新的小部件。您是否真的要这样做,还是只能创建一次Home等实例,然后在用户单击按钮时将其隐藏或显示?

我认为这是闪烁的主要原因。单击主页按钮,它将创建一个主页窗口。单击概述,它会创建一个概述窗口并将其覆盖在主窗口顶部。再次单击“主页”,您将获得另一个“主页”窗口。依此类推。

第二个问题是您直接调用__init__方法。你不应该那样做。创建类的实例(例如: h = Home(master))时,将自动调用__init__。这也可能导致闪烁,因为每次您为窗口创建窗口小部件时,最终都会两次创建窗口小部件。

最后,Home等应该LeftMenu继承。每次单击按钮时,都会创建一组 extra 按钮。实际上是两组额外的按钮。一次创建Overview的实例,一次直接调用__init__的{​​{1}}。

全部添加:

  • 当您单击“概述”时,它会创建一个Overview的新实例。这个新实例中包含X个小部件。
  • 然后您直接调用Overview,它会创建X个其他小部件。
  • 由于它们是从__init__继承的,因此您还将两次创建所有按钮的新副本。

每次您单击其中一个按钮时,就会发生这种情况。

所有这些小部件都堆叠在一起,导致tkinter每次单击按钮时都必须对几何进行大量重新计算。点击次数越多,它必须执行的重新计算就越多。

相关问题