首頁 >後端開發 >Python教學 >如何有效管理 PyQt 應用程式中的執行緒?

如何有效管理 PyQt 應用程式中的執行緒?

Barbara Streisand
Barbara Streisand原創
2024-10-19 11:40:301054瀏覽

How to Effectively Manage Threads in PyQt Applications?

如何利用Python 的PyQt 函式庫來管理執行緒

PyQt 為在Python 應用程式中建立圖形使用者介面提供了一個強大的框架。為了確保執行後台任務時 UI 更新流暢且反應靈敏,Qt 利用與主 GUI 執行緒同時執行的執行緒。然而,有效地使用線程需要仔細考慮。

如 Maya Posch 的文章所述,重新實作 run 方法不應成為使用 QThreads 時的首選方法。相反,請考慮使用訊號和插槽來促進線程之間的通訊。為了說明正確的實現,將提供一個實際範例。

PyQt 執行緒管理範例

在範例中,我們建立一個單獨的工作執行緒來處理長運算而主 GUI 執行緒則管理圖形介面。工作執行緒透過訊號將狀態更新傳達給 GUI。

要開始計算,使用者點選「開始」按鈕。 “取消”按鈕可用於終止操作並重設工作執行緒。請注意,通常不建議強制終止線程,但用於演示目的。

Python 程式碼

<code class="python">from PyQt4 import QtGui, QtCore
import sys
import random

class Example(QtCore.QObject):

    signalStatus = QtCore.pyqtSignal(str)

    def __init__(self, parent=None):
        super(self.__class__, self).__init__(parent)

        # Create a gui object.
        self.gui = Window()

        # Create a new worker thread.
        self.createWorkerThread()

        # Make any cross object connections.
        self._connectSignals()

        self.gui.show()


    def _connectSignals(self):
        self.gui.button_cancel.clicked.connect(self.forceWorkerReset)
        self.signalStatus.connect(self.gui.updateStatus)
        self.parent().aboutToQuit.connect(self.forceWorkerQuit)


    def createWorkerThread(self):

        # Setup the worker object and the worker_thread.
        self.worker = WorkerObject()
        self.worker_thread = QtCore.QThread()
        self.worker.moveToThread(self.worker_thread)
        self.worker_thread.start()

        # Connect any worker signals
        self.worker.signalStatus.connect(self.gui.updateStatus)
        self.gui.button_start.clicked.connect(self.worker.startWork)


    def forceWorkerReset(self):      
        if self.worker_thread.isRunning():
            print('Terminating thread.')
            self.worker_thread.terminate()

            print('Waiting for thread termination.')
            self.worker_thread.wait()

            self.signalStatus.emit('Idle.')

            print('building new working object.')
            self.createWorkerThread()


    def forceWorkerQuit(self):
        if self.worker_thread.isRunning():
            self.worker_thread.terminate()
            self.worker_thread.wait()


class WorkerObject(QtCore.QObject):

    signalStatus = QtCore.pyqtSignal(str)

    def __init__(self, parent=None):
        super(self.__class__, self).__init__(parent)

    @QtCore.pyqtSlot()        
    def startWork(self):
        for ii in range(7):
            number = random.randint(0,5000**ii)
            self.signalStatus.emit('Iteration: {}, Factoring: {}'.format(ii, number))
            factors = self.primeFactors(number)
            print('Number: ', number, 'Factors: ', factors)
        self.signalStatus.emit('Idle.')

    def primeFactors(self, n):
        i = 2
        factors = []
        while i * i <= n:
            if n % i:
                i += 1
            else:
                n //= i
                factors.append(i)
        if n > 1:
            factors.append(n)
        return factors


class Window(QtGui.QWidget):

    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.button_start = QtGui.QPushButton('Start', self)
        self.button_cancel = QtGui.QPushButton('Cancel', self)
        self.label_status = QtGui.QLabel('', self)

        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.button_start)
        layout.addWidget(self.button_cancel)
        layout.addWidget(self.label_status)

        self.setFixedSize(400, 200)

    @QtCore.pyqtSlot(str)
    def updateStatus(self, status):
        self.label_status.setText(status)


if __name__=='__main__':
    app = QtGui.QApplication(sys.argv)
    example = Example(app)
    sys.exit(app.exec_())</code>

此範例示範了 QThreads 在PyQt 應用程序,允許高效的後台操作,而不會凍結使用者介面。

以上是如何有效管理 PyQt 應用程式中的執行緒?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn