当前位置: 首页 > 知识库问答 >
问题:

为什么从工作线程更新tkinter小部件似乎工作?

金高轩
2023-03-14

在研究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()

据我所知,由标记的行???注释是问题。但是这个代码运行得很好。保持响应,标签和进度条都会更新。

共有1个答案

宗鸿博
2023-03-14

有一件事在普通的消费者应用程序中是不可接受的:当你点击“开始”按钮,然后在进度条完成之前关闭窗口时会发生什么?在具有相互依赖部分的大型应用程序中,销毁在另一个线程中使用的gui元素可能会产生令人不快的后果。我发现,当在终端中运行时,这个程序有时会挂在一个意外的出口上,ctrl-c没有任何效果。

顺便提一下

s += (1 / i ** 2)

行正在进行整数除法,因此s的值只更改一次。

 类似资料:
  • 当我试图从我的web服务器获取SOAP响应时,我的小部件更新服务抛出了一个:“android.os.NetworkOnMainThreadException”。 我确信SOAP代码没有错误,因为我只通过IntentService而不是服务在应用程序中使用相同的代码。 我根据最后一个示例设计了我的小部件:http://www.vogella.com/tutorials/AndroidWidgets/

  • 我在Python3.3中有一个Tkinter GUI,带有一个进度条和一个启动另一个线程的按钮。此线程在10秒内填充进度条,并在此期间在控制台上打印0到99之间的数字 只要我不移动或调整GUI窗口的大小,它就可以正常工作。如果我删除标记行为了使工作线程不接触进度条,因此根本不会影响GUI,即使我正在操作窗口,它也会在控制台上连续打印数字。 为什么会发生这种情况?通常会采取什么措施来避免GUI操作导

  • 因此,正如一个人在之前的帖子中所说的,我会使用: 包括行末的“我的文件”。 由于未使用,我想我应该在标准输出中接收操作的结果。然后执行它并获得(注意,我使用而不是只是为了查看是否可以根据需要修改文件,因为在本例中,文件已经有了所需的行): 所以如您所见,文件没有更改。我做错了什么? 感谢阅读

  • 问题内容: 我正在使用JDBC连接到MySQL服务器(我认为没有连接池)。在连接网址中,我有 但是我的连接仍然超时。我什至检查了它的错误。但是,当我尝试使用连接时,出现以下异常。 我知道在Java 1.6中可以使用它来检查连接,但是我正在使用Java 1.5 有没有办法确保它不会超时?还是我必须升级到Java 1.6? 问题答案: 我有同样的问题,这绝对令人发疯。这是文档在MySQL网站上的内容(

  • (线程:持续时间)-->(1:16)、(2,3:32)、(4,5,6,7:47)、(8,9:31)...(17,18,19,20:16) 该项目有2个项目: 工人阶层: 主类:

  • 问题内容: 我正在尝试通过检查golang TCPConn.Write返回的错误来检测发送失败,但它为nil。我也尝试使用TCPConn.SetWriteDeadline,但没有成功。 事情就是这样发生的: 服务器启动 客户端连接 服务器发送一条消息,客户端收到它 客户端 关闭 服务器再发送一条消息:没有错误 服务器发送第三条消息:仅现在出现错误 问题 :为什么只有第二条消息发送给不存在的客户端会