Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk Menguruskan Benang dengan Berkesan dalam Aplikasi PyQt?

Bagaimana untuk Menguruskan Benang dengan Berkesan dalam Aplikasi PyQt?

Barbara Streisand
Barbara Streisandasal
2024-10-19 11:40:30959semak imbas

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>

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!

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