如何在函数fix()
中执行tkinter,等到label's
文本被更改然后再打印end
。
当前工作:当我单击sub
按钮时,将创建新线程并执行for
循环。经过10000000次循环后,我的标签将更改为9999999
。但是在我更改标签之前,tkinter会打印end
。
我尝试了t.join()
,但是它冻结了GUI。
import tkinter as tk
from tkinter import ttk
import threading
root = tk.Tk()
label = tk.Label(text='vinoth')
label.pack()
def fix():
a=0
t = threading.Thread(target=count, args=(a,))
t.start()
#t.join()
print('end')
def count(a):
for i in range(0,10000000):
a=i
label['text'] = a
button = tk.Button(text='sub', command=fix)
button.pack()
dropdown = ttk.Combobox()
dropdown.pack()
root.mainloop()
答案 0 :(得分:2)
您必须小心使用多线程tkinter
应用程序,因为tcl / tk的接口不支持它。这意味着只有主线程才能调用tkinter
及其窗口小部件。
也就是说,您可以通过使用after()
等线程安全机制或通过全局Queue
方法来安排函数定期运行并与线程通信,来解决该限制变量与`Lock'结合使用,以控制对其的并发访问。
这是一个使用后者完成您要完成的任务的示例:
import tkinter as tk
from tkinter import ttk
import threading
POLLING_DELAY = 250 # ms
lock = threading.Lock() # Lock for shared resources.
finished = False
root = tk.Tk()
label = tk.Label(text='vinoth')
label.pack()
def fix():
global finished
with lock:
finished = False
t = threading.Thread(target=count)
t.daemon = True
root.after(POLLING_DELAY, check_status) # Start polling.
t.start()
def check_status():
with lock:
if not finished:
root.after(POLLING_DELAY, check_status) # Keep polling.
else:
print('end')
def count():
global finished
for i in range(10000000):
a = i
with lock:
finished = True
label['text'] = a
button = tk.Button(text='sub', command=fix)
button.pack()
dropdown = ttk.Combobox()
dropdown.pack()
root.mainloop()
答案 1 :(得分:1)
我在while循环中使用root.update()
函数进行了尝试。不知道这是马上做的事!但是无论如何都要发布代码:
import tkinter as tk
from tkinter import ttk
import threading
root = tk.Tk()
class test():
def __init__(self):
self.label = tk.Label(text='vicks')
self.label.pack()
button = tk.Button(text='sub', command=self.fix)
button.pack()
dropdown = ttk.Combobox()
dropdown.pack()
def fix(self):
self.finished = False
t = threading.Thread(target=self.count)
t.daemon = True
t.start()
self.check_status()
print('end')
def check_status(self):
while self.finished is False: #keeps running until the variable finished becomes True
root.update()
def count(self):
a=0
for i in range(100000000):
a = i
self.label['text'] = a
self.finished = True
c = test()
root.mainloop()