How to control QProgressBar with Signal

前端 未结 2 862
遥遥无期
遥遥无期 2021-01-14 19:53

Pushing the button starts 100 rounds cycle. With QLabel.setText() we update self.label from inside of scope of clicked() function.

2条回答
  •  北恋
    北恋 (楼主)
    2021-01-14 20:47

    The code declares a local progressbar object connected to a custom 'customSignal` using:

    QtCore.QObject.connect(self, QtCore.SIGNAL("customSignal(int)"), progressbar, QtCore.SLOT("setValue(int)"))

    with four arguments passed to QtCore.QObject.connect().

    The first argument self is the object that will be emitting the signal. Since the function that will do the "sleep-every-second-processing" is declared under the main Dialog instance we pass self here.

    The second argument is the name of the signal itself: 'customSignal'.

    The progressbar object is used as third and its method setValue as fourth last argument.

    class ProgressBar(QtGui.QProgressBar):
        def __init__(self, parent=None):
            super(ProgressBar, self).__init__(parent=parent)
    
    class Dialog(QtGui.QDialog):
        def __init__(self):
            super(QtGui.QDialog,self).__init__()
            layout = QtGui.QVBoxLayout()
            self.setLayout(layout)
            self.label = QtGui.QLabel('idle...')
            layout.addWidget(self.label)
    
            progressbar = ProgressBar(self)
            QtCore.QObject.connect(self, QtCore.SIGNAL("customSignal(int)"), progressbar, QtCore.SLOT("setValue(int)"))
    
            layout.addWidget(progressbar) 
    
            button = QtGui.QPushButton('Process')
            button.clicked.connect(self.clicked)
            layout.addWidget(button) 
    
        def clicked(self):
            for value in range(101):
                message = '...processing %s of 100'%value
                self.label.setText(message)
                self.emit(QtCore.SIGNAL("customSignal(int)"), value)
                QtGui.qApp.processEvents()
                time.sleep(1)
    
    
    if __name__ == '__main__':
        app = QtGui.QApplication([])
        dialog = Dialog()
        dialog.resize(300, 100)
        dialog.show()
        app.exec_()
    

    --------------------

    Here is variation of the same solution except linking to the progressbar method. import time

    class ProgressBar(QtGui.QProgressBar):
        def __init__(self, parent=None):
            super(ProgressBar, self).__init__(parent=parent)
    
        def set_to_value(self, value):
            self.setValue(value)
            QtGui.qApp.processEvents()
            return True
    
        def closeEvent(self, event):
            self._active=False
    
    class Dialog(QtGui.QDialog):
        def __init__(self):
            QtGui.QDialog.__init__(self, parent=None)
            layout = QtGui.QVBoxLayout()
            self.setLayout(layout)
            self.label = QtGui.QLabel('idle...')
            layout.addWidget(self.label)
    
            progressbar = ProgressBar(self)
            QtCore.QObject.connect(self, QtCore.SIGNAL("customSignal(int)"), progressbar.set_to_value )
            layout.addWidget(progressbar) 
    
            button = QtGui.QPushButton('Process')
            button.clicked.connect(self.clicked)
            layout.addWidget(button) 
    
        def clicked(self):
            for value in range(101):
                message = '...processing %s of 100'%value
                self.label.setText(message)
                self.emit(QtCore.SIGNAL("customSignal(int)"), value)
                QtGui.qApp.processEvents()
                time.sleep(1)
    
    if __name__ == '__main__':
        app = QtGui.QApplication([])
        dialog = Dialog()
        dialog.resize(300, 100)
        dialog.show()
        app.exec_()
    

    ======================

    This code now links a custom signal to a function referred as Slot in Qt.

    from PySide import QtCore, QtGui
    import time
    
    class ProgressBar(QtGui.QProgressBar):
        def __init__(self, parent=None):
            super(ProgressBar, self).__init__(parent=parent)
    
        @QtCore.Slot(int)
        def set_to_value(self, value):
            self.setValue(value)
            QtGui.qApp.processEvents()
            return True
    
        def closeEvent(self, event):
            self._active=False
    
    class Dialog(QtGui.QDialog):
        def __init__(self):
            QtGui.QDialog.__init__(self, parent=None)
            layout = QtGui.QVBoxLayout()
            self.setLayout(layout)
            self.label = QtGui.QLabel('idle...')
            layout.addWidget(self.label)
    
            progressbar = ProgressBar(self)
            # QtCore.QObject.connect(self, QtCore.SIGNAL("customSignal(int)"), progressbar.set_to_value )
            QtCore.QObject.connect(self, QtCore.SIGNAL("customSignal(int)"), progressbar, QtCore.SLOT("set_to_value(int)"))
    
            layout.addWidget(progressbar) 
    
            button = QtGui.QPushButton('Process')
            button.clicked.connect(self.clicked)
            layout.addWidget(button) 
    
        def clicked(self):
            for value in range(101):
                message = '...processing %s of 100'%value
                self.label.setText(message)
                self.emit(QtCore.SIGNAL("customSignal(int)"), value)
                QtGui.qApp.processEvents()
                time.sleep(1)
    
    if __name__ == '__main__':
        dialog = Dialog()
        dialog.resize(300, 100)
        dialog.show()
    

提交回复
热议问题