在 tkinter 中 运行 mainloop 之后更新文本

updating text after running mainloop in tkinter

我想在调用 mainloop() 后更改框架中显示的文本。我创建了 loginfo 函数来在我的字符串中附加文本,但没有任何反应。 GUI 启动并显示其中最初包含的文本(“hi”),我没有看到我通过 loginfo 函数添加的文本(“hello”),退出 GUI 后出现以下错误。

Traceback (most recent call last):
  File "1.py", line 5, in <module>
    monitor.loginfo()
  File "/home/shreyas/Desktop/test/main.py", line 45, in loginfo
    self.text.configure(state='normal')
  File "/usr/lib/python3.8/tkinter/__init__.py", line 1637, in configure
    return self._configure('configure', cnf, kw)
  File "/usr/lib/python3.8/tkinter/__init__.py", line 1627, in _configure
    self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: invalid command name ".!frame.!text"

我的任务是创建一个函数,我将随时使用要插入的文本调用该函数。 该函数将在主循环 运行ning 之后调用,因为我收到要显示的文本。

这些是我创建的 2 个文件:

main.py

import tkinter
from tkinter import *

class Monitor:
    def __init__(self):
        self.root = Tk()
        self.root.title('Monitor')
        self.root.geometry("800x400")
        self.root.grid_columnconfigure((0,1), weight=1)
        self.root.grid_rowconfigure(0, weight=1)

        """-----------------------------------------------"""
        self.console = Frame(self.root,borderwidth=1)
        self.console.grid(row = 0, column = 0, sticky = W+E+N+S)

        self.console.grid_columnconfigure(0, weight=1)
        self.console.grid_rowconfigure(2, weight=1)

        self.lbl_c = Label(self.console, text="console",bg='white')
        self.lbl_c.grid(row = 1, column = 0, sticky = W+E+N+S)

        self.text = tkinter.Text(self.console)
        self.text.grid(row = 2, column = 0,rowspan = 3, columnspan = 1, sticky = N+S+E+W)
        self.text.insert(tkinter.END,"hi")
        self.text.configure(state='disabled')
        """------------------------------------------------"""
        self.fm = Frame(self.root,borderwidth=1)
        self.fm.grid(row = 0, column = 1, sticky = W+E+N+S)

        self.fm.grid_columnconfigure(0, weight=1)
        self.fm.grid_rowconfigure(2, weight=1)

        self.lbl_fm = Label(self.fm, text="frequency_monitor",bg='white')
        self.lbl_fm.grid(row = 1, column = 0, sticky = W+E+N+S)

        self.text1 = tkinter.Text(self.fm)
        self.text1.grid(row = 2, column = 0,rowspan = 1, columnspan = 1, sticky = N+S+E+W)
        self.text1.insert(tkinter.END,"<---------- Frequency Monitor ---------->\n\n"+"Camera100\n"+"Frequency: 9.6 CPU Time: 3.0ms\n"+("----------------------------------------")+"Screen100\n"+"Frequency: 29.8 CPU Time: 6.0ms\n"+("----------------------------------------"))
        self.text1.configure(state='disabled')
        


    def loginfo(self):
        self.text.configure(state='normal')
        self.text.insert(tkinter.END,"hello")
        self.text.update()
        self.text.configure(state='disabled')

1.py

import main as m

monitor = m.Monitor()
monitor.root.mainloop()
monitor.loginfo()

我使用 python 3.1 到 运行 我的代码。谁能告诉我是什么导致了错误,我怎样才能达到预期的结果。

更新: 当我像这样使用 mainloop() 时

import main as m

monitor = m.Monitor()
monitor.root.mainloop()
monitor.root.update()
monitor.root.update_idletasks()
monitor.loginfo()

我得到同样的错误但是当我使用 while

import main as m

monitor = m.Monitor()
#monitor.root.mainloop()
#monitor.loginfo()


while True:
    monitor.root.update()
    monitor.root.update_idletasks()
    monitor.loginfo()

自从我在 while 中调用 loginfo 以来,它会更新文本并不断更新它,但是如果我在 while 循环之外调用它,它不会更新。

mainloop() 之后的代码仅在您的应用程序关闭后才会被调用。所以应用程序关闭后,方法被调用,但是方法中使用的widgets被销毁。因此,将您的代码更改为:

monitor = Monitor()
monitor.loginfo()
monitor.root.mainloop()

这样,该函数将在您退出 GUI 之前被调用。将 mainloop() 视为一个 while 循环,该循环不断更新直到 window 关闭。技术上说 mainloop() 等同于:

while True: # Only exits, because update cannot be used on a destroyed application
    root.update()
    root.update_idletasks()

编辑: 由于您想要延迟,因此您必须添加一个按钮或在 GUI 处于活动状态时调用此方法的东西,例如使用 after 在一段时间后显示该功能,例如:

monitor = Monitor()

monitor.root.after(1000,monitor.loginfo) # Cause a delay of 1 second or 1000 millisecond 

monitor.root.mainloop()