Bagaimana untuk Menguruskan Benang dengan Berkesan dalam Aplikasi PyQt?

Barbara Streisand
Lepaskan: 2024-10-19 11:40:30
asal
1051 orang telah melayarinya

How to Effectively Manage Threads in PyQt Applications?

Cara Menggunakan Perpustakaan PyQt Python untuk Mengurus Benang

PyQt menyediakan rangka kerja yang teguh untuk membina antara muka pengguna grafik dalam aplikasi Python. Untuk memastikan kemas kini UI yang lancar dan responsif semasa melaksanakan tugas latar belakang, Qt menggunakan urutan yang berjalan serentak dengan urutan GUI utama. Walau bagaimanapun, penggunaan benang secara berkesan memerlukan pertimbangan yang teliti.

Seperti yang digariskan dalam artikel Maya Posch, pelaksanaan semula kaedah larian tidak seharusnya menjadi pendekatan pilihan apabila bekerja dengan QThreads. Sebaliknya, pertimbangkan untuk menggunakan isyarat dan slot untuk memudahkan komunikasi antara benang. Untuk menggambarkan pelaksanaan yang betul, contoh praktikal akan dibentangkan.

Contoh Pengurusan Benang PyQt

Dalam sampel, kami mencipta benang pekerja berasingan yang mengendalikan pengiraan panjang manakala utas GUI utama menguruskan antara muka grafik. Urutan pekerja menyampaikan kemas kini status kepada GUI melalui isyarat.

Untuk memulakan pengiraan, pengguna mengklik butang "Mula". Butang "Batal" boleh digunakan untuk menamatkan operasi dan menetapkan semula benang pekerja. Sila ambil perhatian bahawa penamatan benang secara paksa biasanya tidak disyorkan tetapi digunakan untuk tujuan demonstrasi.

Kod Python

<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>
Salin selepas log masuk

Contoh ini menunjukkan penggunaan QThreads yang betul dalam Aplikasi PyQt, membolehkan operasi latar belakang yang cekap tanpa membekukan antara muka pengguna.

Atas ialah kandungan terperinci Bagaimana untuk Menguruskan Benang dengan Berkesan dalam Aplikasi PyQt?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php
Kenyataan Laman Web ini
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
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan