gpt4 book ai didi

Python Tkinter 标签每 10 秒重绘一次

转载 作者:太空狗 更新时间:2023-10-30 01:42:53 32 4
gpt4 key购买 nike

我有以下 Python Tkinter 代码,每 10 秒重绘一次标签。我的问题是,对我来说,它似乎是在旧标签上一遍又一遍地绘制新标签。所以,最终,几个小时后会有数百张绘图重叠(至少从我的理解来看)。这会使用更多内存还是会导致问题?

import Tkinter as tk
import threading

def Draw():
frame=tk.Frame(root,width=100,height=100,relief='solid',bd=1)
frame.place(x=10,y=10)
text=tk.Label(frame,text='HELLO')
text.pack()

def Refresher():
print 'refreshing'
Draw()
threading.Timer(10, Refresher).start()

root=tk.Tk()
Refresher()
root.mainloop()

在我的示例中,我只使用了一个标签。我知道我可以使用 textvariable 来更新标签的文本,甚至 text.config .但实际上我在做的是刷新标签网格(如表格)+按钮和其他内容以匹配最新可用数据。

根据我初学者的理解,如果我将这个 Draw() 函数写成类,我可以使用 frame.destroy 销毁 frame每当我执行 Refresher 函数时。但是我目前的代码是用没有类的函数编写的(我不希望将整个代码重写到类中)。

我能想到的另一个选择是将 Draw() 中的 frame 声明为全局并使用 frame.destroy() (我不愿意这样做,因为如果我有太多的框架(我这样做),这可能会导致名称冲突)

如果 overdraw 旧图不会造成任何问题(除了我看不到旧图),我可以接受。

这些只是我的初学者想法。我应该在重新绘制更新的框架之前销毁框架吗?如果是这样,如果代码结构就像我的示例代码中一样,我应该以什么方式销毁它?还是 overdraw 旧标签就好了?

编辑

有人提到 python tkinter 不是线程安全的,我的代码可能会随机失败。

我其实拿了this link作为使用 threading 作为我的解决方案的引用,我在那篇文章中没有找到任何关于线程安全的信息。

我想知道在哪些情况下我不应该使用threading,在哪些情况下我可以使用threading

最佳答案

在 tkinter 中运行函数或更新标签的正确方法是使用 after方法。这会将事件放在事件队列中,以便在将来的某个时间执行。如果您有一个函数可以完成一些工作,然后将其自身放回事件队列,那么您就创建了一个将永远运行的函数。

这是一个基于您的示例的简单示例:

import Tkinter as tk
import time

def Draw():
global text

frame=tk.Frame(root,width=100,height=100,relief='solid',bd=1)
frame.place(x=10,y=10)
text=tk.Label(frame,text='HELLO')
text.pack()

def Refresher():
global text
text.configure(text=time.asctime())
root.after(1000, Refresher) # every second...

root=tk.Tk()
Draw()
Refresher()
root.mainloop()

从编码风格的角度来看,我会对该程序进行很多更改,但我希望它尽可能接近您的原始问题。重点是,您可以使用 after 调用更新标签的函数,而无需创建新标签。另外,该函数可以安排在某个时间间隔再次调用它自己。在此示例中,我选择了一秒钟,以便更容易看到效果。

您还问“我想知道在什么情况下我不应该使用线程,在什么情况下我可以使用线程?”

直截了本地说,如果你不得不问一个关于何时使用线程的问题,你就不应该使用线程。线程是一种高级技术,它很复杂,而且很容易出错。线程很可能会使您的程序变慢而不是变快。它会产生微妙的后果,例如,如果您执行非线程安全的操作,您的程序就会莫名其妙地失败。

更具体地说明您的情况:您应该避免将线程与 tkinter 一起使用。您可以使用它们,但不能从这些其他线程访问小部件。如果您需要对小部件执行某些操作,则必须将一条指令放入线程安全队列中,然后在主线程中您需要定期检查该队列以查看是否有要处理的指令。如果您搜索它们,本网站上有这样的示例。

如果这一切听起来很复杂,那确实是。对于您编写的大多数 GUI,您无需担心这一点。如果您可以采用大型进程并将它们分解为在 100 毫秒或更短时间内执行的 block ,则您只需要 after,而永远不需要线程。

关于Python Tkinter 标签每 10 秒重绘一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17847869/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com