"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > كيفية إدارة المواضيع بشكل فعال في تطبيقات PyQt؟

كيفية إدارة المواضيع بشكل فعال في تطبيقات PyQt؟

تم النشر بتاريخ 2024-11-03
تصفح:658

How to Effectively Manage Threads in PyQt Applications?

كيفية استخدام مكتبة PyQt في Python لإدارة المواضيع

يوفر PyQt إطارًا قويًا لبناء واجهات المستخدم الرسومية في تطبيقات Python. لضمان تحديثات واجهة المستخدم السلسة والمستجيبة أثناء تنفيذ مهام الخلفية، تستخدم Qt الخيوط التي تعمل بشكل متزامن مع سلسلة واجهة المستخدم الرسومية الرئيسية. ومع ذلك، فإن استخدام سلاسل الرسائل بشكل فعال يتطلب دراسة متأنية.

كما هو موضح في مقالة Maya Posch، لا ينبغي أن تكون إعادة تنفيذ طريقة التشغيل هي الطريقة المفضلة عند العمل مع QThreads. بدلاً من ذلك، فكر في استخدام الإشارات والفتحات لتسهيل الاتصال بين سلاسل العمليات. لتوضيح التنفيذ الصحيح سيتم تقديم مثال عملي.

مثال على إدارة سلاسل PyQt

في العينة، نقوم بإنشاء مؤشر ترابط عامل منفصل يتعامل مع العمليات الحسابية الطويلة بينما يدير مؤشر ترابط واجهة المستخدم الرسومية الرئيسي الواجهة الرسومية. يقوم مؤشر ترابط العامل بتوصيل تحديثات الحالة إلى واجهة المستخدم الرسومية من خلال الإشارات.

لبدء الحساب، ينقر المستخدم على زر "ابدأ". يمكن استخدام الزر "إلغاء" لإنهاء العملية وإعادة ضبط مؤشر ترابط العامل. يرجى ملاحظة أن الإنهاء القسري لسلسلة المحادثات لا يُنصح به عمومًا ولكنه يُستخدم لأغراض العرض التوضيحي.

كود بايثون

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  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_())

يوضح هذا المثال الاستخدام الصحيح لـ QThreads في تطبيق PyQt، مما يسمح بعمليات خلفية فعالة دون تجميد واجهة المستخدم.

بيان الافراج أعيد طبع هذه المقالة على: 1729302445 في حالة وجود أي مخالفة، يرجى التواصل مع [email protected] لحذفها
أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3