【发布时间】:2014-07-15 17:14:37
【问题描述】:
我在研究 tkinter 多线程时看到的所有地方,我发现提到 tkinter 必须在主线程上运行(就像许多 GUI 框架一样),当一个单独的线程需要与 GUI 通信时, 必须使用队列而不是直接从工作线程访问小部件。
我试图学习使用队列方法,但当然一开始我想看看如果我做错了会发生什么,所以我写了这段代码,它在几秒钟内逼近 Pi (π):
import tkinter as tk
from tkinter import ttk
from threading import Thread
import math
window = tk.Tk()
window.geometry("300x150")
lbl = tk.Label(window, text="Press Start")
lbl.place(width=280, height=60, x=10, y=10)
pb = ttk.Progressbar(window)
pb.place(width=280, height=25, x=10, y=80)
def calculate():
""" 1 / i^2 = PI^2 / 6 """
s = 0.0
for i in range(1, 10000001):
s += (1 / i**2)
if i % 1000000 == 0:
value = math.sqrt(s * 6)
lbl.config(text=value) #???
pb.step(10) #???
def start():
lbl.config(text="Press Start")
#calculate() #irresponsive GUI this way, obviously
t = Thread(target=calculate)
t.start()
btn = tk.Button(window, text="Start", command=start)
btn.place(width=280, height=25, x=10, y=115)
window.mainloop()
据我了解,??? 注释标记的行是问题所在。但是这段代码运行得很好。保持响应,标签和进度条都会更新。
这个跨线程错误是否有时会发生/有时不会发生?这段代码最终可能会破坏吗?还是我天真地认为唯一好的解决方案是排队?我相信在 C# 中这会产生一个cross-thread operation not valid,但 python 似乎没有问题。
【问题讨论】:
-
在这段代码中,太简单了,没有问题。当您有许多线程试图同时更新同一个小部件时,就会出现问题。
-
@dilbert 我明白了,谢谢。
-
我写了一个类似的代码,在 Mac (python 3.6) 上运行良好,但在 Linux (python 3.5) 上崩溃了。错误是“
out of stack space (infinite loop?)”
标签: python multithreading tkinter