嘗試更新在具有“main”函式變數的執行緒上運行的 tkinter“textvariable”。我實作了一個基于執行緒的解決方案,因此 tkinter 主回圈后面的代碼可以運行:https ://stackoverflow.com/a/1835036/15409926 。
請分享我如何解決此錯誤。如果這不是更新“textvariable”的最簡單方法,請分享替代方法。
代碼:
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 視窗顯示初始“文本變數”
錯誤:
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'
uj5u.com熱心網友回復:
大多數 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.uj5u.com/ruanti/340151.html
