pyqt

使用PyQt線程的正確姿式前端

用了Python一段時間了,圖形編程看了一些,仍是以爲PyQt比較方便,主要得益於designer和uic兩個工具,使得前端頁面可視編程,也方便轉換爲代碼。關於這兩個工具的使用網上一大堆,我以爲並無必要重複,只有有一點要提醒你們注意,就是用uic生成的程序文件千萬別動!!!新寫一個類繼承它,須要增長的方法都放在子類裏面,這樣咱們從新修改ui文件,再用uic生成代碼的時候就不用再修改太多(若是不修改已有的控件名就不用修改)。編程

說到圖形界面,就避開不了線程,畢竟UI主線程必須保證事件循環不被阻塞來響應用戶的輸入。一開始使用PyQt的時候,程序動不動就未響應,後來才知道是由於把須要長時間運行的代碼放在了主線程,阻塞了事件循環。這時候,咱們便須要把這部分代碼移到其餘線程,經過信號與槽來實現線程間的通訊。所謂線程,按照我目前的理解,是包含了本身的事件循環機制,所謂事件循環,也就是說當線程接收到信號的時候,若是有響應的槽,能夠作出響應。同時,線程還能夠發送信號給其餘線程,信號能夠帶參數。網絡

因爲寫博客的時間有點倉儲,本博客裏面的代碼所有是截取我最近的項目裏面的代碼,但跟博客內容有關的部分我會盡可能呈現和說明清楚,望見諒。多線程

QtCore.QThread是一個管理線程的類,當咱們使用其構造函數的時候,便新建了一個線程。這裏要強調,QThread是一個線程管理器,不要把業務邏輯放在這個類裏面,Qt的做者已經屢次批評繼承QThread類來實現業務邏輯的作法。那麼,咱們怎樣把代碼放到Thread中運行呢?答案以下:ide

self.writing_thread = QtCore.QThread()
self.writer.moveToThread(self.writing_thread)
咱們把業務邏輯寫在一個QtCore.QObject的子類裏面,而後新建一個實例,例如上述代碼的writer,而後調用繼承了父類的方法moveToThread,這樣就能夠把該對象放在線程裏面。剩下的工做就是經過信號和槽的機制處理業務邏輯和返回結果了。通常來講,槽函數所在的類在哪一個線程,這個函數就在哪一個線程執行。函數

http://www.javashuo.com/article/p-uctpfrei-ed.html工具

pyqt多線程moveToThread的使用ui

建立一個QObject子類
該類包含要在子線程中運行的代碼,以及在子線程運行過程當中須要發回主線程的信號。如下爲例:

class AnalyzObject(QObject):
    def __init__(self,parent=None):
        super(AnalyzObject,self).__init__(parent)
    #開始調用網絡的信號
    stop_analyz_signal=pyqtSignal()
    start_print_result=pyqtSignal()
    
    def analyz_work(self):
        test_video()
        self.start_print_result.emit()      
        self.stop_analyz_signal.emit()

其中,analyz_work是要子線程中所要運行的代碼。

實例化QObject子類,並轉移到子線程中。
回到主線程,先將AnalyzObject(本例中)實例化,再新建立一個子線程,將實例化的AnalyzObject轉移到子線程中,如下爲代碼:
self.analyz_thread=QThread()
self.analyze=AnalyzObject()
self.analyze.moveToThread(self.analyz_thread)
        
開始線程
在但願激活子線程的時候加入代碼:
self.analyz_thread.started.connect(self.analyze.analyz_work)
self.analyz_thread.start()
結束線程
self.analyze.stop_analyz_signal.connect(self.stop_analyze)
def stop_analyze(self):
    self.analyz_thread.quit()
相關文章
相關標籤/搜索