Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk Melaksanakan QThreads dalam PyQt untuk Aplikasi GUI Responsif?

Bagaimana untuk Melaksanakan QThreads dalam PyQt untuk Aplikasi GUI Responsif?

Susan Sarandon
Susan Sarandonasal
2024-10-19 09:55:02942semak imbas

How to Implement QThreads in PyQt for Responsive GUI Applications?

Pelaksanaan QThread yang Betul dalam PyQt

Dalam aplikasi PyQt Gui, mengasingkan operasi yang panjang kepada urutan yang berasingan selalunya diingini untuk mengekalkan responsif GUI. Walau bagaimanapun, melaksanakan semula kaedah larian adalah tidak digalakkan mengikut rujukan yang dinyatakan dalam soalan.

Untuk menunjukkan pendekatan yang betul dalam Python, pertimbangkan contoh berikut yang menggunakan isyarat dan slot untuk komunikasi antara GUI dan benang pekerja :

  1. Buat Benang Pekerja: Mulakan objek pekerja dan alihkannya ke urutan berasingan untuk dimulakan.
  2. Sambungkan Isyarat dan Slot: Wujudkan sambungan isyarat dan slot antara pekerja dan objek GUI untuk kemas kini status.
  3. Mulakan Benang Pekerja: Apabila butang "Mula" diklik, GUI memberi isyarat kepada utas pekerja untuk mulakan pengiraan.
  4. Batalkan Benang Pekerja: Jika perlu, butang "Batal" secara paksa menamatkan urutan pekerja dan mencipta yang baharu.

Berikut ialah pelaksanaan kod:

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

Dengan mematuhi pendekatan ini, anda boleh menggunakan QThreads dalam aplikasi PyQt dengan berkesan, memastikan GUI kekal responsif walaupun semasa operasi yang panjang.

Atas ialah kandungan terperinci Bagaimana untuk Melaksanakan QThreads dalam PyQt untuk Aplikasi GUI Responsif?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn