Heim  >  Artikel  >  Backend-Entwicklung  >  Wie verwaltet man Threads in PyQt-Anwendungen effektiv?

Wie verwaltet man Threads in PyQt-Anwendungen effektiv?

Barbara Streisand
Barbara StreisandOriginal
2024-10-19 11:40:30959Durchsuche

How to Effectively Manage Threads in PyQt Applications?

So nutzen Sie die PyQt-Bibliothek von Python zum Verwalten von Threads

PyQt bietet ein robustes Framework zum Erstellen grafischer Benutzeroberflächen in Python-Anwendungen. Um reibungslose und reaktionsschnelle UI-Updates bei der Ausführung von Hintergrundaufgaben zu gewährleisten, verwendet Qt Threads, die gleichzeitig mit dem Haupt-GUI-Thread ausgeführt werden. Der effektive Einsatz von Threads erfordert jedoch sorgfältige Überlegungen.

Wie im Artikel von Maya Posch dargelegt, sollte die Neuimplementierung der run-Methode nicht der bevorzugte Ansatz bei der Arbeit mit QThreads sein. Erwägen Sie stattdessen die Verwendung von Signalen und Slots, um die Kommunikation zwischen Threads zu erleichtern. Um die korrekte Implementierung zu veranschaulichen, wird ein praktisches Beispiel vorgestellt.

Beispiel für PyQt-Thread-Management

Im Beispiel erstellen wir einen separaten Worker-Thread, der lange Berechnungen abwickelt während der Haupt-GUI-Thread die grafische Oberfläche verwaltet. Der Worker-Thread kommuniziert Statusaktualisierungen über Signale an die GUI.

Um die Berechnung zu starten, klickt der Benutzer auf die Schaltfläche „Start“. Über die Schaltfläche „Abbrechen“ kann der Vorgang abgebrochen und der Worker-Thread zurückgesetzt werden. Bitte beachten Sie, dass die erzwungene Thread-Beendigung nicht allgemein empfohlen wird, sondern zu Demonstrationszwecken verwendet wird.

Python-Code

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

Dieses Beispiel demonstriert die ordnungsgemäße Verwendung von QThreads in a PyQt-Anwendung, die effiziente Hintergrundvorgänge ermöglicht, ohne dass die Benutzeroberfläche einfriert.

Das obige ist der detaillierte Inhalt vonWie verwaltet man Threads in PyQt-Anwendungen effektiv?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn