Python Tkinter程序正在使用forget()崩溃
在我的程序中,我想在按钮上使用“忘记”。现在如果我尝试,程序就会崩溃。我知道这与线程有关,但我还没有找到解决方案。提前谢谢。下面是我的示例代码:Python Tkinter程序正在使用forget()崩溃,python,multithreading,python-2.7,crash,tkinter,Python,Multithreading,Python 2.7,Crash,Tkinter,在我的程序中,我想在按钮上使用“忘记”。现在如果我尝试,程序就会崩溃。我知道这与线程有关,但我还没有找到解决方案。提前谢谢。下面是我的示例代码: import Tkinter as tk import thread window = tk.Tk() def ok(): pass def voice(): button1.forget() print("If you see this, it works!") thread.start
import Tkinter as tk
import thread
window = tk.Tk()
def ok():
pass
def voice():
button1.forget()
print("If you see this, it works!")
thread.start_new_thread(voice,())
button1=tk.Button(command=ok, text="PRESS")
button1.pack()
window.mainloop()
Tkinter因其缺乏线程安全性而臭名昭著,这意味着您编写的代码有时可以工作,有时会导致整个程序挂起而不产生错误,这是一种痛苦 幸运的是,Tkinter确实有自己的方法来处理这个问题,所以要启动一个包含语音的线程,只需调用语音。但是,在语音结束时,请确保您使用了window.after方法,以便稍后再次调用它。例如:
import Tkinter as tk
import thread
window = tk.Tk()
def ok():
pass
def voice():
button1.forget()
print("If you see this, it works!")
window.after(10, voice())
voice()
button1=tk.Button(command=ok, text="PRESS")
button1.pack()
window.mainloop(
除了创建对象的线程外,您不能从任何线程访问tkinter对象。换句话说,您不能从线程调用button1.forget并期望它可靠地工作
普遍接受的解决方案是让线程将信息写入线程安全队列,让GUI线程周期性地轮询该队列,拉出一个项目,并执行该项目请求的任何操作 因此,我使用mtTkinter模块简单地解决了这个问题,您可以在这里找到:
要使用它,您只需在开始时将import mtTkinter作为Tkinter编写。之后,您可以正常使用您的Tkinter。此模块不会更改Tkinter中的任何内容,只会使其对线程友好。访问创建它的线程以外的线程中的小部件,往往会使Tkinter翻转并崩溃。为什么在这里使用线程呢?直接发出按钮的命令声音。@kevin好吧,这只是一个示例代码。在我的实际程序中,我使用pyttsx,为此我需要线程。也许你可以重构你的代码,使所有特定于Tkinter的操作都在主线程上进行。例如,voice将全局应忘设置为True,root有一个after_idle回调方法,该方法定期检查应忘是否为True,并根据需要调用forget。原始问题不会在计时器上运行任何内容,所以我不认为添加计时器能解决任何问题。他发布了希望利用多线程和tkinter的代码,这是完全不可能的。我冒昧地假设他的最终目标是让某些东西与主线程同时运行,否则使用线程有什么意义呢。我发布的解决方案提供了他可能需要的所有信息,但他决定实施他的计划。这取决于他如何使用它。那么我能做些什么来回避这个问题呢?@Duardo:我已经稍微更新了我的答案。如果您搜索此网站,则有此解决方案的示例。