如何在 PyQt 中為響應式 GUI 應用程式實作 QThreads?

Susan Sarandon
發布: 2024-10-19 09:55:02
原創
940 人瀏覽過

How to Implement QThreads in PyQt for Responsive GUI Applications?

PyQt 中QThread 的正確實作

在PyQt Gui 應用程式中,通常需要將冗長的操作分離到單獨的執行緒中以分離到單獨的執行緒中以保持GUI 回應能力。但是,不鼓勵按照問題中提到的參考重新實作 run 方法。

為了示範Python 中的正確方法,請考慮以下範例,該範例利用訊號和槽在GUI 和工作執行緒之間進行通訊:

  1. 建立一個工作執行緒:初始化一個工作物件並將其移至一個單獨的執行緒來啟動。
  2. 連接訊號和槽: 在工作執行緒和 GUI 物件之間建立訊號和槽連接以進行狀態更新。
  3. 啟動工作執行緒: 當「開始」按鈕時,GUI 會向工作執行緒發出訊號啟動計算。
  4. 取消工作執行緒:如果需要,「取消」按鈕會強制終止工作執行緒並建立一個新執行緒。

這裡是程式碼實作:

<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)

        self.gui = Window()
        self.createWorkerThread()
        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):
        self.worker = WorkerObject()
        self.worker_thread = QtCore.QThread()
        self.worker.moveToThread(self.worker_thread)
        self.worker_thread.start()

        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>
登入後複製

透過遵循這種方法,您可以在PyQt 應用程式中有效地利用QThreads,確保GUI 即使在長時間操作期間也能保持響應。

以上是如何在 PyQt 中為響應式 GUI 應用程式實作 QThreads?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!