读取文件时不断更新 tkinter 应用程序

Continiously update tkinter app while reading the file

我正在 tkinter 中设计应用程序,我需要每秒逐行读取一个文件并在小部件上查看结果,也是每秒。问题是我的程序正在读取整个文件,并且只有在更新我的 Gui 之后。

class Gui(Frame):
def __init__(self, master):
    super(Gui, self).__init__()
    self.master = master

    # ... here are my tkinter widgets 

    self.ser = None
    self.start_update()

def start_update(self):
    if self.ser is None:
        self.ser = open("serial.txt") # open only once
        self.updater()  

def updater(self):
    while True:
        self.raw_line = self.ser.readline()
        if self.raw_line:

            # here I update labels with .configure() method
            self.after(1000, self.updater)
        else:
            print('Probably end of file')
            self.ser.close()
            self.ser = None # can open again

root = Tk()
gui = Gui(root)
root.mainloop()

答案很简单:在处理 GUI 的主线程中有一个无限循环。结果,GUI 一直挂起,直到循环中断。

这是一个简单的修复方法:

class MainWindow(Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.file = None
        self.update_from_file()
        self.master.protocol('WM_DELETE_WINDOW', self.on_close)

    def open_file(self, filename="serial.txt"):
        if self.file is not None:
            self.file = open(filename)

    def update_from_file(self):
        line = self.file.readline()
        if line:
            # update the widgets
            # reminder : when applicable, use tkinter variables
            # as they are easier to handle than manually updating with .config()
        self.after(1000, self.update_from_file)

    def on_close(self):
        self.file.close()
        self.file = None # can open again

root = Tk()
gui = MainWindow(root)
root.mainloop()

这样,update_from_file 方法在处理时不会挂起主线程。

如果您需要额外的 CPU 空间,另一个有效的选项是使用 threading 创建一个单独的线程,并使用它从文件中读取。这也不会挂起 tkinter 线程,因为两个线程是分开的。如果您打算在文件打开时对其进行编辑,则必须小心竞争条件。