您好,登錄后才能下訂單哦!
? 首先要講的是一個TKinter使用時常常遇到的問題,因為TKinter自身刷新GUI是單線程的,用戶在調用mainloop方法后,主線程會一直不停循環刷新GUI,但是如果用戶給某個widget綁定了一個很耗時的方法A時,這個方法A也是在主線程里調用,于是這個耗時的方法A會阻塞住刷新GUI的主線程,表現就是整個GUI卡住了,只有等這個耗時的方法結束后,GUI才會對用戶操作響應。
代碼如下:
from Tkinter import
from ttk import
import time
class GUI():
def __init__(self, root):
self.initGUI(root)
def initGUI(self, root):
root.title("test")
root.geometry("400x200+700+500")
root.resizable = False
self.button_1 = Button(root, text="run A", width=10, command=self.A)
self.button_1.pack(side="top")
self.button_2 = Button(root, text="run B", width=10, command=self.B)
self.button_2.pack(side="top")
root.mainloop()
def A(self):
print "start to run proc A"
time.sleep(3)
print "proc A finished"
def B(self):
print "start to run proc B"
time.sleep(3)
print "proc B finished"
if name == "main":
root = Tk()
myGUI = GUI(root)
function(){ //MT4教程:http://www.kaifx.cn/mt4.html
? ? ? 很簡單一段代碼,GUI里只有兩個button,分別綁定了兩個耗時3秒的方法A和方法B,首先我點擊了上面一個button調用方法A,在A運行期間,我又調用了方法B,可以看到在方法A運行期間,方法B并沒有運行,而是等A運行完之后,才運行了方法B,而且在方法A運行過程中,整個GUI沒有響應我對下面一個button的點擊,而且GUI界面無法拖拽,只有兩個方法結束后才拖拽起來。
最簡單的解決上述問題的辦法就是利用多線程,把兩個耗時方法丟到兩個子線程里運行,就可以避開主線程被阻塞的問題,所以對上面代碼稍稍修改一下,如下所示:
from Tkinter import
from ttk import
import threading
import time
class GUI():
def __init__(self, root):
self.initGUI(root)
def initGUI(self, root):
root.title("test")
root.geometry("400x200+700+500")
root.resizable = False
self.button_1 = Button(root, text="run A", width=10, command=self.A)
self.button_1.pack(side="top")
self.button_2 = Button(root, text="run B", width=10, command=self.B)
self.button_2.pack(side="top")
root.mainloop()
def __A(self):
print "start to run proc A"
time.sleep(3)
print "proc A finished"
def A(self):
T = threading.Thread(target=self.__A)
T.start()
def __B(self):
print "start to run proc B"
time.sleep(3)
print "proc B finished"
def B(self):
T = threading.Thread(target=self.__B)
T.start()
if name == "main":
root = Tk()
myGUI = GUI(root)
然而,事情并不會就這么簡單結束了,實際應用中,我們的GUI不可能只有兩個簡單的Button,有時候,我們也有需要即時刷新GUI自身的情況,比如我們假設有這么一個簡單的GUI程序,界面只有一個Button和一個Text,點擊Button后,每隔一秒將當前時間打印到Text上,也就說,在這個程序里,我們需要動態修改widget。
本來,一般理想情況下,用戶點擊了button之后,應該會立即能在Text里顯示出當前時間,然而在這個例子里,我們可以看到,用戶點擊Button之后,隔了三秒,才將所有的輸出一次顯示出來,原因還是之前提到的, TKinter本身是單線程的,顯示時間這個方法耗時3秒,會卡住主線程,主線程在這三秒內去執行顯示時間的方法去了,GUI不會立即刷新,代碼如下:
from Tkinter import
from ttk import
import threading
import time
import sys
def fmtTime(timeStamp):
timeArray = time.localtime(timeStamp)
dateTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
return dateTime
class re_Text():
def __init__(self, widget):
self.widget = widget
def write(self, content):
self.widget.insert(INSERT, content)
self.widget.see(END)
class GUI():
def __init__(self, root):
self.initGUI(root)
def initGUI(self, root):
root.title("test")
root.geometry("400x200+700+500")
root.resizable = False
self.button = Button(root, text="click", width=10, command=self.show)
self.button.pack(side="top")
self.scrollBar = Scrollbar(root)
self.scrollBar.pack(side="right", fill="y")
self.text = Text(root, height=10, width=45, yscrollcommand=self.scrollBar.set)
self.text.pack(side="top", fill=BOTH, padx=10, pady=10)
self.scrollBar.config(command=self.text.yview)
sys.stdout = re_Text(self.text)
root.mainloop()
def show(self):
i = 0
while i < 3:
print fmtTime(time.time())
time.sleep(1)
i += 1
if name == "main":
root = Tk()
myGUI = GUI(root)
? ? ? ? ?? 上面這段代碼的GUI里只有一個button和一個Text,我將標準輸出stdout重定向到了一個自定義的類里,這個類的write方法可以更改Text的內容,具體就不細說了,如果對重定向標準輸出還不了解的,可以自行百度或者Google。
? ? ? ? ?? 這個時候,如果對Tkinter不熟悉的同學肯定會想,我把上面代碼里的show方法丟到子線程里去跑,不就可以解決這個問題了,那我們就先嘗試一下,再改一改代碼:
from Tkinter import
from ttk import
import threading
import time
import sys
def fmtTime(timeStamp):
timeArray = time.localtime(timeStamp)
dateTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
return dateTime
class re_Text():
def __init__(self, widget):
self.widget = widget
def write(self, content):
self.widget.insert(INSERT, content)
self.widget.see(END)
class GUI():
def __init__(self, root):
self.initGUI(root)
def initGUI(self, root):
root.title("test")
root.geometry("400x200+700+500")
root.resizable = False
self.button = Button(root, text="click", width=10, command=self.show)
self.button.pack(side="top")
self.scrollBar = Scrollbar(root)
self.scrollBar.pack(side="right", fill="y")
self.text = Text(root, height=10, width=45, yscrollcommand=self.scrollBar.set)
self.text.pack(side="top", fill=BOTH, padx=10, pady=10)
self.scrollBar.config(command=self.text.yview)
sys.stdout = re_Text(self.text)
root.mainloop()
def __show(self):
i = 0
while i < 3:
print fmtTime(time.time())
time.sleep(1)
i += 1
def show(self):
T = threading.Thread(target=self.__show, args=())
T.start()
if name == "main":
root = Tk()
myGUI = GUI(root)
原文鏈接:https://blog.csdn.net/u013700771/article/details/103321783
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。