Wie implementiert man QThreads in PyQt für Responsive GUI-Anwendungen?

Susan Sarandon
Freigeben: 2024-10-19 09:55:02
Original
940 Leute haben es durchsucht

How to Implement QThreads in PyQt for Responsive GUI Applications?

Korrekte Implementierung von QThreads in PyQt

In PyQt-GUI-Anwendungen ist es oft wünschenswert, langwierige Vorgänge in separate Threads aufzuteilen, um die Reaktionsfähigkeit der GUI aufrechtzuerhalten. Von einer erneuten Implementierung der Ausführungsmethode wird jedoch gemäß der in der Frage genannten Referenz abgeraten.

Um den richtigen Ansatz in Python zu demonstrieren, betrachten Sie das folgende Beispiel, das Signale und Slots für die Kommunikation zwischen der GUI und dem Arbeitsthread verwendet :

  1. Erstellen Sie einen Worker-Thread:Initiieren Sie ein Worker-Objekt und verschieben Sie es in einen separaten Thread, der gestartet werden soll.
  2. Signale und Slots verbinden: Stellen Sie Signal- und Slot-Verbindungen zwischen den Worker- und GUI-Objekten für Statusaktualisierungen her.
  3. Worker-Thread starten: Wenn auf die Schaltfläche „Start“ geklickt wird, signalisiert die GUI dem Worker-Thread dies Berechnungen starten.
  4. Worker-Thread abbrechen: Bei Bedarf beendet die Schaltfläche „Abbrechen“ den Worker-Thread zwangsweise und erstellt einen neuen.

Hier ist der Code-Implementierung:

<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>
Nach dem Login kopieren

Durch die Einhaltung dieses Ansatzes können Sie QThreads in PyQt-Anwendungen effektiv nutzen und sicherstellen, dass die GUI auch bei langwierigen Vorgängen reaktionsfähig bleibt.

Das obige ist der detaillierte Inhalt vonWie implementiert man QThreads in PyQt für Responsive GUI-Anwendungen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php
Erklärung dieser Website
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
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!