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

问题描述 投票:1回答:1

我正在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()
python tkinter updating
1个回答
0
投票

答案很简单:在处理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线程。但是,如果您打算在打开文件时进行编辑,则必须谨慎对待竞争条件。

© www.soinside.com 2019 - 2024. All rights reserved.