Python 每n秒显示一个消息框后重复一个功能
我想设置一个函数,以便在显示消息框后再次重复。 下面是一个简短的代码示例,这正是我想要做的Python 每n秒显示一个消息框后重复一个功能,python,multithreading,tkinter,setinterval,Python,Multithreading,Tkinter,Setinterval,我想设置一个函数,以便在显示消息框后再次重复。 下面是一个简短的代码示例,这正是我想要做的 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("Regr
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")
一切正常,但问题是,一旦消息框显示为“无响应错误”。请任何人帮助找出解决方案,您将需要使用.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()
您将需要使用.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()
线程和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
时),线程仍会继续运行!因此,如果你试图实现一些简单的事情,这是一个选择(快速和小的选择)
但是,如果您顽固地或真的需要创建(覆盖)线程对象的自定义子类,它将为您提供更大的灵活性来控制流
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()
- 对于复杂和长时间执行的事情-
是您的选择李>线程化
- 此外,当事情变得复杂时:
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
时),线程仍会继续运行!因此,如果你试图实现一些简单的事情,这是一个选择(快速和小的选择)
但是,如果您顽固地或真的需要创建(覆盖)线程对象的自定义子类,它将为您提供更大的灵活性来控制流
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()
- 对于复杂和长时间执行的事情-
是您的选择李>线程化
- 此外,当事情变得复杂时: