Rumah >pembangunan bahagian belakang >Tutorial Python >Bagaimana Menggunakan QThreads Dengan Betul dalam PyQt: Amalan Terbaik dan Contoh Penggunaan?

Bagaimana Menggunakan QThreads Dengan Betul dalam PyQt: Amalan Terbaik dan Contoh Penggunaan?

Linda Hamilton
Linda Hamiltonasal
2024-10-19 10:08:30540semak imbas

How to Use QThreads Properly in PyQt: Best Practices and Example Usage?

Cara Menggunakan QThread Dengan Betul dalam PyQt

QThread Latar Belakang

QThreads membolehkan anda mencipta dan laksanakan tugas dalam urutan yang berasingan, menyelaraskan operasi yang mungkin membekukan antara muka pengguna. Walau bagaimanapun, catatan blog https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/ mengesyorkan agar tidak melaksanakan semula kaedah larian untuk menggunakan QThreads .

Penggunaan QThread yang Betul

Daripada memanipulasi kaedah larian, pertimbangkan amalan terbaik berikut untuk penggunaan QThread dalam PyQt:

Contoh Penggunaan

Kod di bawah memberikan contoh benang pekerja berasingan yang berkomunikasi dengan GUI menggunakan isyarat:

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

Dalam contoh ini, GUI dan benang pekerja adalah objek berasingan yang berkomunikasi melalui isyarat. GUI mendengar kemas kini status, manakala urutan pekerja melakukan pengiraan dan menghantar semula kemajuan.

Atas ialah kandungan terperinci Bagaimana Menggunakan QThreads Dengan Betul dalam PyQt: Amalan Terbaik dan Contoh Penggunaan?. 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