【问题标题】:How to control QProgressBar with Signal如何用 Signal 控制 QProgressBar
【发布时间】:2016-05-10 11:01:33
【问题描述】:

按下按钮开始 100 轮循环。使用QLabel.setText(),我们从clicked() 函数的范围内更新self.label

除了更新self.label,我们还想更新progressbar。 但是由于progressbar 是一个局部变量,我们不能从onClick() 函数内部更新它。

import time

class ProgressBar(QtGui.QProgressBar):
    def __init__(self, parent=None, total=20):
        super(ProgressBar, self).__init__(parent=parent)

        self.setMinimum(1)
        self.setMaximum(105)        
        self.setTextVisible(True) 

    def set_to_value(self, value):
        self.setValue(value)
        QtGui.qApp.processEvents()

    def closeEvent(self, event):
        self._active=False


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)
        layout.addWidget(progressbar) 

        button = QtGui.QPushButton('Process')
        button.clicked.connect(self.onClick)
        layout.addWidget(button) 

    def onClick(self):
        for i in range(101):
            message = '...processing %s of 100'%i
            self.label.setText(message)
            QtGui.qApp.processEvents()
            time.sleep(1)


if __name__ == '__main__':
    app = QtGui.QApplication([])
    dialog = Dialog()
    dialog.resize(300, 100)
    dialog.show()
    app.exec_()

【问题讨论】:

  • 你为什么要手动拨打qApp.processEvents()
  • 该示例似乎不涉及线程或其他进程...我认为问题标题不正确?如果您实际使用线程,还需要考虑其他注意事项。
  • @three_pineapples:我只是想让我的问题中的代码尽可能简单。目标是找到一种方法来从声明小部件的实例外部、另一个外部线程内部或另一个外部进程内部控制一个小部件。

标签: python qt pyqt qprogressbar


【解决方案1】:

将进度条声明为:

self.progressbar = ProgressBar(self)

【讨论】:

    【解决方案2】:

    代码声明了一个本地 progressbar 对象,它使用以下方法连接到自定义“customSignal”:

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

    四个参数传递给QtCore.QObject.connect()

    第一个参数self 是发出信号的对象。由于将执行“每秒睡眠处理”的函数是在 Dialog 主实例下声明的,因此我们在此处传递 self

    第二个参数是信号本身的名称:'customSignal'。

    progressbar 对象用作第三个参数,其方法 setValue 用作倒数第四个参数。

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

    --------

    除了链接到进度条方法之外,这是相同解决方案的变体。 进口时间

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

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

    此代码现在将自定义信号链接到 Qt 中称为 Slot 的函数。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-11
      • 1970-01-01
      • 1970-01-01
      • 2018-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多