1. 程式人生 > >wxpython後臺執行緒更新介面控制元件方法

wxpython後臺執行緒更新介面控制元件方法

在大多數的GUI應用程式中,在應用程式的後臺中長期執行一個處理過程而不干涉使用者與應用程式的其它部分的互動是有好處的。允許後臺處理的機制通常是產生一個執行緒並在該執行緒中長期執行一個處理過程。對於wxPython的多執行緒有兩點需要特別說明。

最重要的一點是,GUI的操作必須發生在主執行緒或應用程式的主迴圈所處的地方中。在一個單獨的執行緒中執行GUI操作對於無法預知的程式崩潰和除錯來說是一個好的辦法。基於技術方面的原因,如許多UnixGUI庫不是執行緒安全性的,以及在微軟WindowsUI物件的建立問題,wxPython沒有設計它自己的發生在多執行緒中的事件,所以我們建議你也不要嘗試。如果你在更新

UI介面時不使用,那麼你可能會遇到奇怪的問題。有時GUI也忙執行挺正常,有時卻會無緣無故的崩潰。上面的禁令包括與螢幕互動的任何專案,尤其包括wx.Bitmap物件。

對於wxPython應用程式,關於所有UI的更新,後臺執行緒只負責傳送訊息給UI執行緒,而不關心GUI的更新。幸運的是,wxPython沒有強制限定你能夠有的後臺執行緒的數量。\

最常用的技術是使用wx.CallAfter()函式,wxPython的全域性函式wx.CallAfter(),該函式是傳遞訊息給你的主執行緒的最容易的方法wx.CallAfter()使得主執行緒在當前的事件處理完成後,可以對一個不同的執行緒呼叫一個函式。傳遞給

wx.CallAfter()的函式物件總是在主執行緒中被執行。

#執行測試並把執行過程列印到日誌監控介面

def runSuit(self,event):

        #在這裡建立一個後臺執行緒

       thread.start_new_thread(runSuitFunc,(self,self.logText,self.selected,self.panel))

#使用後臺執行緒呼叫RunTest.runSuit1執行測試並監測執行過程,並生成測試報告

defrunSuitFunc(self,logText,suitSelected,panel):

   testsuit=RunTest.runSuit1(suitSelected,logText)

    gbReport=GbReport.GbReport()

    RES=gbReport.generateHtmlReport(testsuit)

    #GUI的更新必須在主迴圈處進行,使用wx.CallAfter來達到這個目的

    wx.CallAfter(self.generateFigure,RES,self.panel)

thread.exit_thread()

#顯示測試結果統計資訊和統計圖,更新GUI,這個函式是在主迴圈中進行的

    def generateFigure(self,testRes,panel):

        #在左側顯示測試執行結果統計資訊

       font=wx.Font(9,wx.DEFAULT,wx.NORMAL,wx.BOLD)

        resStr="用例集總共用例數:"+str(testRes[1])

        print resStr

       self.totalSuitText=wx.StaticText(self.panel,-1,resStr,(20,250))

        self.totalSuitText.SetFont(font)

        resStr="執行成功用例個數:"+str(testRes[2])

       self.successSuitText=wx.StaticText(self.panel,-1,resStr,(20,280))

        self.successSuitText.SetFont(font)

        resStr="不存在的用例個數:"+str(testRes[3])

       self.failSuitText=wx.StaticText(self.panel,-1,resStr,(20,310))

        self.failSuitText.SetFont(font)

        resStr="執行失敗用例個數:"+str(testRes[4])

        self.notexistSuitText=wx.StaticText(self.panel,-1,resStr,(20,340))

        self.notexistSuitText.SetFont(font)

        #在右側顯示測試執行結果統計圖

        figPath=testRes[0]

        img1 = wx.Image(figPath,wx.BITMAP_TYPE_ANY)

        w = img1.GetWidth()

        h = img1.GetHeight()

        img1 = img1.Scale(w/2,h/2)

        img1 = img1.ConvertToBitmap()

        wx.StaticBitmap(self.panel,-1,img1,(160,225),(w/2,h/2))

        self.panel.Refresh()