2017-04-11 61 views
0

我想設置一個函數,在顯示消息框後再次重複。 簡短的代碼示例如下所示的是什麼,我究竟想要做每隔n秒顯示一個消息框後重復一次函數

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") 

所有的東西都是好的,但問題是唯一的,一旦messgae框中顯示出其給予「沒有響應錯誤」 .Anyone請幫助找出解決方案

回答

1

您將需要使用.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() 
0

線程和Tk不拌勻,因爲他們違反了使用傳統知識的Tcl/Tk線程模型只是從一個線程和你的代碼不工作,因爲你佔據了主力的(唯一)線!

當你的打印功能打印保存 - GUI是unresponsible因爲這一點,你可以用另一個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()是一個選項(快速和小的選擇)。

但是,如果你stubborny或真的需要這個 - 創建(覆蓋)線程對象的自定義子類,它給你更多的靈活性來控制你的流量!

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是你的選擇!

鏈接:

+0

感謝名單了很多它會幫助我很多 –