線程和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
是你的選擇!
鏈接:
感謝名單了很多它會幫助我很多 –