我想设置一个功能,在显示消息框后再次重复。 下面显示了一个简短的代码示例,即我想要做的事情
def setInterval(func,time,args):
e = threading.Event()
while not e.wait(time):
func(args)
def foo(data):
print data
aa("what")
def aa(a):
print(a)
tkMessageBox.showinfo("Regret","nope")
setInterval(foo,5,"fsrty")
一切都还可以,但问题只是一旦显示的杂物盒给出“没有响应错误”。任何人请帮助找出解决方案
答案 0 :(得分:2)
你将需要使用.after方法,因为线程永远不能很好地运行这个tkinter,也不会使用while循环。
import Tkinter as tk
import TkMessageBox
def setInterval(func,time,args):
func(args)
root.after(time, setInterval(func, time, args))
root.tk.Tk()
root.withdraw()
def foo(data):
print data
aa("what")
def aa(a):
print(a)
tkMessageBox.showinfo("Regret","nope")
setInterval(foo, 5, "fsrty")
root.mainloop()
答案 1 :(得分:0)
线程和Tk不能很好地混合,因为它们违反了仅使用来自一个线程的Tk的Tcl / Tk线程模型而且你的代码不起作用,因为你占用了主要的(一个且唯一的) )线程!
虽然您的打印功能会继续打印 - 因此GUI不负责任,您可以使用代码中的其他print
轻松检查:
>>> print('**** Active threads: %d ****' % threading.active_count())
**** Active threads: 1 ****
所以你真正需要的就是创造另一个!
try:
import tkinter as tk
from tkinter import messagebox as msgbox
except ImportError:
import Tkinter as tk
import TkMessageBox as msgbox
import threading
def setInterval(func,time,args):
e = threading.Event()
while not e.wait(time):
print('**** Active threads: %d ****' % threading.active_count())
func(args)
def foo(data):
print(data)
aa("what")
def aa(a):
print(a)
root = tk.Tk()
print('**** Active threads: %d ****' % threading.active_count())
thread = threading.Thread(target=setInterval, args=(foo, 5, "fsrty"))
msgbox.showinfo("Regret", "nope")
thread.start()
root.mainloop()
但是这是另一个问题 - 即使在你关闭GUI之后(当你转义mainloop
时)线程仍在运行!因此,如果您想要实现简单的事情 - .after()
是一个选项(快速和小的替代方案)。
但如果你很顽固或真的需要这个 - 创建(覆盖)线程对象的自定义子类,它可以让你更灵活地控制你的流程!
try:
import tkinter as tk
from tkinter import messagebox as msgbox
except ImportError:
import Tkinter as tk
import TkMessageBox as msgbox
import threading
class Thread(threading.Thread):
def __init__(self):
super(Thread, self).__init__()
self.running = False
self.function_to_execute = None
self._stop = threading.Event()
def start_thread(self, func, *args, **kwargs):
self.function_to_execute = (func, args, kwargs)
self.running = True
self.start()
def run(self):
print('### STARTED ###')
while self.running:
try:
print('### RUNNING ###')
function, args, kwargs = self.function_to_execute
function(*args, **kwargs)
except:
self.stop()
def stop(self):
print('### STOPPING ###')
self.running = False
self._stop.set()
def setInterval(func, time, args):
e = threading.Event()
e.wait(time)
print('**** Active threads: %d ****' % threading.active_count())
func(args)
def foo(data):
print(data)
aa('what')
def aa(a):
print(a)
def clear():
thread.stop()
while True:
try:
thread.is_alive()
except TypeError:
root.destroy()
print('### STOPPED ###')
print('**** Active threads: %d ****' % threading.active_count())
break
root = tk.Tk()
thread = Thread()
print('**** Active threads: %d ****' % threading.active_count())
msgbox.showinfo("Regret", "nope")
thread.start_thread(setInterval, foo, 5, 'fsrty')
root.protocol('WM_DELETE_WINDOW', clear)
root.mainloop()
如你所见 - 当我们在退出之前试图清理时,事情变得越来越复杂,但它确实有效!
<强>结论:强>
.after()
是一个不错的选择!threading
是您的选择!<强>链接:强>