खोज…


परिचय

प्रगति बार्स उपयोगकर्ता अनुभव का एक अभिन्न हिस्सा हैं और उपयोगकर्ताओं को GUI पर चलने वाली किसी दिए गए प्रक्रिया के लिए बचे समय पर एक विचार प्राप्त करने में मदद करता है। यह विषय आपके स्वयं के अनुप्रयोग में प्रगति पट्टी को लागू करने की मूल बातों पर जाएगा।

यह विषय हल्के ढंग से क्यूथ्रेड और नए सिग्नल / स्लॉट तंत्र पर स्पर्श करेगा। PyQt5 विगेट्स के कुछ बुनियादी ज्ञान भी पाठकों से अपेक्षित हैं।

उदाहरण जोड़ते समय कार्यक्षमता का प्रदर्शन करने के लिए केवल PyQt5 और Python अंतर्निहित इन्स का उपयोग करें।

केवल PyQt5

टिप्पणियों

इन उदाहरणों के साथ प्रयोग करना सीखना शुरू करने का सबसे अच्छा तरीका है।

बेसिक पायकट प्रोग्रेस बार

यह एक बहुत ही बुनियादी प्रगति पट्टी है जो केवल उसी चीज का उपयोग करती है जो नंगे न्यूनतम पर आवश्यक है।

इस पूरे उदाहरण को अंत तक पढ़ना बुद्धिमानी होगी।

import sys
import time

from PyQt5.QtWidgets import (QApplication, QDialog,
                             QProgressBar, QPushButton)

TIME_LIMIT = 100

class Actions(QDialog):
    """
    Simple dialog that consists of a Progress Bar and a Button.
    Clicking on the button results in the start of a timer and
    updates the progress bar.
    """
    def __init__(self):
        super().__init__()
        self.initUI()
        
    def initUI(self):
        self.setWindowTitle('Progress Bar')
        self.progress = QProgressBar(self)
        self.progress.setGeometry(0, 0, 300, 25)
        self.progress.setMaximum(100)
        self.button = QPushButton('Start', self)
        self.button.move(0, 30)
        self.show()

        self.button.clicked.connect(self.onButtonClick)

    def onButtonClick(self):
        count = 0
        while count < TIME_LIMIT:
            count += 1
            time.sleep(1)
            self.progress.setValue(count)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Actions()
    sys.exit(app.exec_())

प्रगति पट्टी को पहले from PyQt5.QtWidgets import QProgressBar तरह from PyQt5.QtWidgets import QProgressBar

फिर इसे QtWidgets में किसी भी अन्य विजेट की तरह इनिशियलाइज़ किया QtWidgets

लाइन self.progress.setGeometry(0, 0, 300, 25) विधि x,y को डायलॉग और प्रगति बार की चौड़ाई और ऊंचाई पर परिभाषित करती है।

हम फिर .move() का उपयोग करके बटन को 30px नीचे की ओर ले जाते हैं ताकि दोनों विजेट्स के बीच 5px अंतर हो।

यहाँ self.progress.setValue(count) का उपयोग प्रगति को अपडेट करने के लिए किया जाता है। .setMaximum() का उपयोग करके एक अधिकतम मान सेट करना भी स्वचालित रूप से आपके लिए मूल्यों की गणना करेगा। उदाहरण के लिए, यदि अधिकतम मान 50 के रूप में सेट किया गया है, तो TIME_LIMIT 100 के बाद से यह हर सेकंड 0 से 1 के बजाय 2 से 4 प्रतिशत हो जाएगा। आप दिए गए मान से प्रारंभ करने के लिए प्रगति पट्टी का उपयोग करके .setMinimum() का उपयोग करके एक न्यूनतम मान भी सेट कर सकते हैं।

इस कार्यक्रम को निष्पादित करने से इसके समान जीयूआई का उत्पादन होगा।

प्रगति बार डायलॉग का जवाब नहीं

जैसा कि आप देख सकते हैं, जब तक TIME_LIMIT शर्त पूरी नहीं हो जाती, GUI निश्चित रूप से फ्रीज और अनुत्तरदायी रहेगा। ऐसा इसलिए है क्योंकि time.sleep OS को विश्वास time.sleep है कि प्रोग्राम अनंत लूप में फंस गया है।

QThread

तो हम इस मुद्दे को कैसे दूर करेंगे? हम थ्रेडिंग क्लास का उपयोग कर सकते हैं जो PyQt5 प्रदान करता है।

import sys
import time

from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import (QApplication, QDialog,
                             QProgressBar, QPushButton)

TIME_LIMIT = 100

class External(QThread):
    """
    Runs a counter thread.
    """
    countChanged = pyqtSignal(int)

    def run(self):
        count = 0
        while count < TIME_LIMIT:
            count +=1
            time.sleep(1)
            self.countChanged.emit(count)

class Actions(QDialog):
    """
    Simple dialog that consists of a Progress Bar and a Button.
    Clicking on the button results in the start of a timer and
    updates the progress bar.
    """
    def __init__(self):
        super().__init__()
        self.initUI()
        
    def initUI(self):
        self.setWindowTitle('Progress Bar')
        self.progress = QProgressBar(self)
        self.progress.setGeometry(0, 0, 300, 25)
        self.progress.setMaximum(100)
        self.button = QPushButton('Start', self)
        self.button.move(0, 30)
        self.show()

        self.button.clicked.connect(self.onButtonClick)

    def onButtonClick(self):
        self.calc = External()
        self.calc.countChanged.connect(self.onCountChanged)
        self.calc.start()

    def onCountChanged(self, value):
        self.progress.setValue(value)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Actions()
    sys.exit(app.exec_())

आइए इन संशोधनों को तोड़ते हैं।

from PyQt5.QtCore import QThread, pyqtSignal

यह पंक्ति Qthread आयात Qthread जो पृष्ठभूमि में एक प्रोग्राम के कुछ भागों को विभाजित करने और चलाने के लिए PyQt5 कार्यान्वयन है (जैसे कि बहु-थ्रेडिंग के रूप में भी जाना जाता है)। इन भागों को थ्रेड्स भी कहा जाता है। डिफ़ॉल्ट रूप से सभी PyQt5 प्रोग्रामों में एक मुख्य धागा होता है और अन्य (वर्कर थ्रेड्स) का उपयोग अतिरिक्त समय लेने को बंद करने और मुख्य कार्यक्रम को कार्यशील रखते हुए गहन कार्यों को पृष्ठभूमि में संसाधित करने के लिए किया जाता है।

दूसरा आयात pyqtSignal का उपयोग कार्यकर्ता और मुख्य थ्रेड्स के बीच डेटा (सिग्नल) भेजने के लिए किया जाता है। इस उदाहरण में हम इसका उपयोग प्रगति पट्टी को अद्यतन करने के लिए मुख्य सूत्र को बताने के लिए करेंगे।

अब हमने काउंटर के लिए लूप को अलग वर्ग में स्थानांतरित कर दिया है जिसे External कहा जाता है।

class External(QThread):
    """
    Runs a counter thread.
    """
    countChanged = pyqtSignal(int)

    def run(self):
        count = 0
        while count < TIME_LIMIT:
            count +=1
            time.sleep(1)
            self.countChanged.emit(count)

QThread उप-वर्गीकृत करके हम अनिवार्य रूप से External को एक वर्ग में परिवर्तित कर रहे हैं जिसे एक अलग धागे में चलाया जा सकता है। इसके लाभ को जोड़ते हुए थ्रेड्स को किसी भी समय शुरू या बंद किया जा सकता है।

यहाँ countChanged वर्तमान प्रगति और है pyqtSignal(int) बताता कार्यकर्ता धागा कि संकेत किया जा रहा है भेजा प्रकार का है int । हालांकि, self.countChanged.emit(count) मुख्य धागे में किसी भी कनेक्शन को संकेत भेजता है (आमतौर पर इसका उपयोग अन्य श्रमिक थ्रेड्स के साथ भी संवाद करने के लिए किया जा सकता है)।

def onButtonClick(self):
        self.calc = External()
        self.calc.countChanged.connect(self.onCountChanged)
        self.calc.start()

def onCountChanged(self, value):
    self.progress.setValue(value)

जब बटन पर क्लिक किया जाता है तो self.onButtonClick चलेगा और थ्रेड भी शुरू करेगा। धागा .start() साथ शुरू किया गया है। यह भी ध्यान दिया जाना चाहिए कि हमने सिग्नल से कनेक्ट किया था। self.calc.countChanged हमने प्रगति बार वैल्यू को अपडेट करने के लिए उपयोग की गई विधि से पहले बनाया था। हर बार जब External::run::count अद्यतन किया जाता है int मूल्य भी करने के लिए भेज दिया जाता है onCountChanged

इन परिवर्तनों को करने के बाद GUI कैसे दिख सकता है।

क्यूथ्रेड प्रोग्रेस बार

यह बहुत अधिक संवेदनशील महसूस करना चाहिए और फ्रीज नहीं होगा।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow