„Wenn ein Arbeiter seine Arbeit gut machen will, muss er zuerst seine Werkzeuge schärfen.“ – Konfuzius, „Die Gespräche des Konfuzius. Lu Linggong“
Titelseite > Programmierung > Wie verwaltet man Threads in PyQt-Anwendungen effektiv?

Wie verwaltet man Threads in PyQt-Anwendungen effektiv?

Veröffentlicht am 03.11.2024
Durchsuche:292

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 eine erzwungene Thread-Beendigung nicht allgemein empfohlen wird, sondern zu Demonstrationszwecken verwendet wird.

Python-Code

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

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

Freigabeerklärung Dieser Artikel wird unter folgender Adresse abgedruckt: 1729302445 Bei Verstößen wenden Sie sich bitte an [email protected], um ihn zu löschen
Neuestes Tutorial Mehr>

Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.

Copyright© 2022 湘ICP备2022001581号-3