在 ttk GUI 中更新期间令人讨厌的灰色闪烁

Annoying grey flicker during updates in ttk GUI

我正在尝试用一些每隔给定时间间隔刷新的数据填充我的屏幕。我正在使用 Python3,主题为 tkinter。每次我的屏幕更新时,我都会在屏幕上看到每个标签的灰色闪烁。有没有办法避免这种情况? P.S : 我正在调用 'after' 方法来刷新数据。

更新:这是一些示例代码:

def button1Click(self):
    self.top = Toplevel(width=600,height=400)
    self.top.title("XYZ ORGANIZATION")
    self.frame1 = Frame(self.top,bg='#009999')
    self.frame1.pack()
    self.noOfEmp = Label(self.frame1,text = "Number_Of_Employees : ", font =('Verdana',9, 'bold'),bg='#009999',fg = '#000000')
    self.noOfEmp.grid(row=1,column=0,sticky=W,padx=0,pady=5)
    self.TeamLabel = Label(self.frame1,text = "Team Name : ", font =('Verdana',9, 'bold'),bg='#009999',fg = '#000000')
    self.TeamLabel.grid(row=2,column=0,sticky=W,padx=0,pady=5)      

    self.text = Text(self.frame1, bg='#009999')
    self.text.grid(row=8,columnspan=17)
    self.old_emp = 0
    self.EFile = open('/abc','r').readlines()
    for line in self.EFile:
        if line.startswith('EmpTotal:'):
            self.Tot_Emp = int(line.split()[1])
            break
    t1 = threading.Thread(target=self.__make_layout, args = ())
    t1.daemon = True
    t1.start()
    t2 = threading.Thread(target=self.ProcEmp,args = ())
    t2.daemon = True
    t2.start()

def self.__make_layout:
    self.CLabelVal = Label(self.frame1,text = CSpace, font=('Verdana',9),bg='#009999',fg = '#000000')
    self.MLabelVal = Label(self.frame1,text = MSpace  , font =('Verdana',9),bg='#009999',fg = '#000000')
    self.Label1Val.grid(row=4,column=1,sticky=W+E+N+S,padx=5,pady=5)                              
    self.Label2Val.grid(row=5,column=1,sticky=W+E+N+S,padx=5,pady=5)
    self.frame1.after(5000,self.__make_layout)

我根据你提供的做了一个小程序

这就是我得到的。我选择了 500 毫秒,因为我不想等那么久。我 运行 同时播放两个互联网视频,没有任何问题。 所以我最好的猜测是您的视频卡速度较慢或计算机负载过重。

from tkinter import *

class MyClass:

    frame1 = Tk()
    poll = 0

    def __init__(self):
        self.frame1.after(500, self.__make_layout)

    def __make_layout(self):
        self.poll += 1
        CSpace = "Poll count = "*20
        MSpace = str(self.poll)

        self.CLabelVal = Label(self.frame1, text=CSpace, font=('Verdana', 9), bg='#009999', fg='#000000')
        self.MLabelVal = Label(self.frame1, text=MSpace, font=('Verdana', 9), bg='#009999', fg='#000000')
        self.CLabelVal.grid(row=4, column=1, sticky=W+E+N+S, padx=5, pady=5)
        self.MLabelVal.grid(row=5, column=1, sticky=W+E+N+S, padx=5, pady=5)
        print(CSpace, MSpace)
        return self.frame1.after(500, self.__make_layout)


MyClass()
mainloop()

这不会创建更多标签并使用 "textvariable" 更新功能。

from tkinter import *


class MyClass:
    frame1 = Tk()
    poll = 0
    textstg = StringVar()
    CSpace = "Poll count"

    def __init__(self):
        self.frame1.after(500, self.__make_layout)
        self.CLabelVal = Label(self.frame1, text=self.CSpace, font=('Verdana', 9), bg='#009999', fg='#000000')
        self.MLabelVal = Label(self.frame1, textvariable=self.textstg, font=('Verdana', 9), bg='#009999', fg='#000000')
        self.CLabelVal.grid(row=4, column=1, sticky=W+E+N+S, padx=5, pady=5)
        self.MLabelVal.grid(row=5, column=1, sticky=W+E+N+S, padx=5, pady=5)

    def __make_layout(self):
        self.poll += 1
        self.textstg.set(str(self.poll))
        return self.frame1.after(50, self.__make_layout)

MyClass()
mainloop()

部分问题是您不断将越来越多的小部件堆叠在一起。您应该只创建一次标签,然后每五秒更改一次它们显示的内容,而不是每五秒创建一个新的小部件。

还有一个问题是您在线程中创建标签。 Tkinter 不是线程安全的。任何创建或修改小部件的代码都需要在主线程中。要更新标签,您不需要线程,但您可以使用线程来更改实际显示的内容。

def __make_layout(self):
    self.CLabelVal = Label(...,text = CSpace, ...)
    self.MLabelVal = Label(...,text = MSpace, ...)
    self.Label1Val.grid(...)                              
    self.Label2Val.grid(...)

def __update_layout(self):
    self.CLabelVal.configure(text=CSpace)
    self.MLabelVal.configure(text=MSpace)
    self.after(5000, self.__update_layout)