「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > PyQt アプリケーションでスレッドを効果的に管理するにはどうすればよいですか?

PyQt アプリケーションでスレッドを効果的に管理するにはどうすればよいですか?

2024 年 11 月 3 日に公開
ブラウズ:466

How to Effectively Manage Threads in PyQt Applications?

Python の PyQt ライブラリを利用してスレッドを管理する方法

PyQt は、Python アプリケーションでグラフィカル ユーザー インターフェイスを構築するための堅牢なフレームワークを提供します。バックグラウンド タスクの実行中にスムーズで応答性の高い UI 更新を保証するために、Qt はメイン GUI スレッドと同時に実行されるスレッドを利用します。ただし、スレッドを効果的に使用するには慎重な検討が必要です。

Maya Posch の記事で概説されているように、QThread を使用する場合、run メソッドの再実装は推奨されるアプローチではありません。代わりに、シグナルとスロットを使用してスレッド間の通信を容易にすることを検討してください。正しい実装を説明するために、実際の例を示します。

PyQt スレッド管理の例

サンプルでは、​​長い計算を処理する別のワーカー スレッドを作成します。一方、メイン GUI スレッドはグラフィカル インターフェイスを管理します。ワーカー スレッドは、ステータスの更新をシグナルを通じて GUI に伝達します。

計算を開始するには、ユーザーは「開始」ボタンをクリックします。 「キャンセル」ボタンを使用すると、操作を終了し、ワーカー スレッドをリセットできます。スレッドの強制終了は一般的に推奨されませんが、デモンストレーションの目的で使用されることに注意してください。

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

この例では、PyQt アプリケーションでの QThread の適切な使用法を示し、ユーザー インターフェイスをフリーズさせることなく効率的なバックグラウンド操作を可能にします。

リリースステートメント この記事は次の場所に転載されています: 1729302445 権利侵害がある場合は、[email protected] に連絡して削除してください。
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3