簡體   English   中英

Python PyQt:是否可以將QThread與非GUI程序一起使用?

[英]Python PyQt: Is it possible to use QThread with a non-GUI program?

我有一個顯示簡單UI的Python PyQt應用程序。 當用戶單擊UI中的按鈕時,它將觸發QThread。 線程的使用可防止UI在線程運行時“凍結”。 我發出信號以將信息從運行線程傳遞回UI,以進行狀態更新並指示完成。 一切都按說明工作正常,我為UI調用創建了一個簡單的類,該類創建線程並運行我的通用處理。

但是,我也想創建程序的命令行版本(無GUI)並使用相同的處理QThread類。 但是,嘗試連接信號時出現以下錯誤。 似乎QThread僅用於GUI程序?

AttributeError: MyClass instance has no attribute 'connect'

是否可以將QThread與非GUI程序一起使用?

from PyQt4 import QtCore
from PyQt4.QtCore import * 

#======================================

class MyProcess(QThread):

    def __init__(self):
        QThread.__init__(self)

    def __del__(self):
        self.quit()
        self.wait()  

    def run(self):
        print "do time intensive process here"  
        self.emit( SIGNAL('processdone'), "emitting signal processdone") 
        return       

#====================================== 

class MyClass(QObject):

    def __init__(self, parent=None):            # All QObjects receive a parent argument (default to None)
        super(MyClass, self).__init__(parent)   # Call parent initializer.

        thread1 = MyProcess()  # uses QThread and emits signal 'processdone' 
        self.connect( thread1, SIGNAL("processdone"), self.thread1done)    
        thread1.start()  

    def thread1done(self):
        print "done"      

#======================================

if __name__ == "__main__": 

    MyClass()

問題不是QThread,而是您正在從沒有它的類中調用connect方法。 您需要使MyClass從QObject繼承。

在GUI中這是可行的,因為您正在使用的任何小部件(QDialog,QMainWindow,QWidget ...)都(直接或間接)繼承自QObject。

要使MyClassQObject繼承,您只需:

class MyClass(QObject):                         # Specify the class your are specializing.
    def __init__(self, parent=None):            # All QObjects receive a parent argument (default to None)
        super(MyClass, self).__init__(parent)   # Call parent initializer.

        # And countinue your code here... 

我還建議您使用新型信號和插槽支持

一切正常,除了processdone信號稱為,但顯然它永遠不會觸發來電thread1done。

我能發現的問題是您尚未定義一個processdone信號。 Qt不存在該信號。 檢查我留下的鏈接以了解自定義信號。 同時,您可以添加:

class MyProcess(QThread):
    processdone = QtCore.pyqtSignal("QString")

在課程開始時。

最后一件事,但非常重要。 您沒有使用GUI,但仍在使用QObjects和Qt信號機制,這取決於要運行的主要Qt循環。 因此,盡管您的應用程序是非GUI程序,但仍然需要QApplication對象。

這是您的代碼,現在可以使用:

from PyQt4 import QtCore
from PyQt4 import QtGui
from PyQt4.QtCore import * 

class MyProcess(QThread):
    processdone = QtCore.pyqtSignal("QString") # Define custom signal.
    def __init__(self, parent = None):
        QThread.__init__(self, parent)
    def run(self):
        print("do time intensive process here")
        self.emit( SIGNAL('processdone'), "emitting signal processdone")
        return       

class MyClass(QObject):

    def __init__(self, parent=None):            # All QObjects receive a parent argument (default to None)
        super(MyClass, self).__init__(parent)   # Call parent initializer.

        thread1 = MyProcess(self) 
        self.connect( thread1, SIGNAL("processdone"), self.thread1done)    
        thread1.start()  

    @QtCore.pyqtSlot("QString")         # Tell Python this is a QTSLOT an receives a string
    def thread1done(self, text):
        print(text)                     # Print the text from the signal.

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)  # You still need a QApplication object.
    a = MyClass()
    sys.exit(app.exec())

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM