尝试使用“main”函数变量更新在线程上运行的 tkinter“textvariable”。我实现了一个基于线程的解决方案,因此 tkinter 主循环后面的代码可以运行:https://stackoverflow.com/a/1835036/15409926 https://stackoverflow.com/a/1835036/15409926.
请分享我如何解决此错误。如果这不是更新“textvariable”的最简单方法,请分享替代方法。
Code:
from tkinter import *
from threading import Thread
class GUI(Thread):
def __init__(self):
Thread.__init__(self)
self.start()
def run(self):
self.root = Tk()
self.var = StringVar()
self.var.set("Initiated")
screen_width = self.root.winfo_screenwidth()
screen_height = self.root.winfo_screenheight()
width = screen_width*.12
height = screen_height
x = screen_width - width
y = screen_height*.025
self.root.geometry('%dx%d+%d+%d' % (width, height, x, y))
label = Label(self.root, textvariable= self.var)
label.pack()
self.root.mainloop()
gui = GUI()
def main():
for i in range(1000):
gui.var.set(f'Current Iteration: {i}')
if __name__ == '__main__':
main()
窗口不更新:Tkinter 窗口显示初始“textvariable” https://i.stack.imgur.com/JPlNJ.png
Error:
Traceback (most recent call last):
File "test.py", line 36, in <module>
main()
File "test.py", line 33, in main
gui.var.set(f'Current Iteration: {i}')
AttributeError: 'GUI' object has no attribute 'var'
大多数 GUI 不喜欢在单独的线程中更改小部件中的值。
你应该使用queue
将值发送到线程,它应该使用root.after(time, function)
定期运行函数,该函数将从队列中获取值并更新 GUI 中的值。
import tkinter as tk # PEP8: `import *` is not preferred
from threading import Thread
import queue
import time # simulate show program
class GUI(Thread):
def __init__(self, queue):
super().__init__()
self.queue = queue
self.start()
def run(self):
self.root = tk.Tk()
self.var = tk.StringVar()
self.var.set("Initiated")
screen_width = self.root.winfo_screenwidth()
screen_height = self.root.winfo_screenheight()
width = int(screen_width*.12)
height = int(screen_height)
x = int(screen_width - width)
y = int(screen_height*.025)
self.root.geometry(f'{width}x{height}+{x}+{y}')
label = tk.Label(self.root, textvariable=self.var)
label.pack()
# run first time after 100ms (0.1 second)
self.root.after(100, self.check_queue)
self.root.mainloop()
def check_queue(self):
#if not self.queue.empty():
while not self.queue.empty():
i = self.queue.get()
self.var.set(f'Current Iteration: {i}')
# run again after 100ms (0.1 second)
self.root.after(100, self.check_queue)
def main():
q = queue.Queue()
gui = GUI(q)
for i in range(1000):
q.put(i)
# simulate show program
time.sleep(0.5)
if __name__ == '__main__':
main()
PEP 8——Python 代码风格指南 https://www.python.org/dev/peps/pep-0008/
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)