中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

TKinter在多線程時刷新GUI的一些碎碎念

發布時間:2020-07-14 16:46:04 來源:網絡 閱讀:791 作者:專注地一哥 欄目:編程語言

? 首先要講的是一個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

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

兴安县| 桐梓县| 黎平县| 南投市| 惠州市| 万州区| 常宁市| 商丘市| 塔河县| 平遥县| 六盘水市| 绥德县| 新余市| 富顺县| 红桥区| 富锦市| 绵阳市| 黄大仙区| 吉林省| 苍南县| 桂东县| 西峡县| 旌德县| 新邵县| 宜兴市| 正镶白旗| 图们市| 牡丹江市| 城市| 聂荣县| 恩平市| 江都市| 泽库县| 梁平县| 木兰县| 定边县| 集贤县| 布拖县| 浦江县| 北流市| 宣威市|