将 PyQT 的 QProgressbar 与生成器结合使用是否有效?

Is using PyQT's QProgressbar in combination with generators efficient?

我正在尝试使用 QProgressBar 更新自身以显示冗长操作的进度。我的代码是:

#yield trials
import sys
from PyQt4.QtGui import QDialog, QProgressBar, QPushButton, \
                    QLabel, QApplication, QVBoxLayout

def someprocess():
    bignumber = 1000000
    for i in range((bignumber+1)): 
        if float(i)/bignumber in [float(count)/10 for count in range(11)]:
            yield i, float(i)/bignumber

if __name__ == "__main__":
    it= someprocess()
    app = QApplication(sys.argv)
    mydialog = QDialog()
    myprogress = QProgressBar()
    mylabel = QLabel("Uninitiated.")
    mylayout = QVBoxLayout()
    mylayout.addWidget(mylabel)
    mylayout.addWidget(myprogress)
    mydialog.setLayout(mylayout)
    mydialog.show()
    try:
        value, percentage = it.next()
        while value != None: 
            value, percentage = it.next()
            myprogress.setValue(percentage*100)
            mylabel.setText("Currently at : %s" % str(value))
    except StopIteration:
        print "Completed!"
    except Exception, e:
        print "Unknown exception: ", repr(e) 
        raise
    sys.exit(app.exec_())

有更好的方法吗?

PyQt(或者一般来说,UI开发)通常需要将耗时较长的运行函数放到后端线程中,这样就不会阻塞你的UI线程,使其能够响应 UI update/User 交互。所以在这种情况下,你需要将“someprocess”放入后端线程(可能继承自QThread),并使用信号槽更新UI。 我修改了您的代码,添加了一些更改。把耗时长的运行函数移到后端线程,现在UI不会卡死了。

import sys
from PyQt4.QtGui import QDialog, QProgressBar, QPushButton, \
                    QLabel, QApplication, QVBoxLayout
from PyQt4.QtCore import QThread, pyqtSignal


def someprocess():
    bignumber = 1000000
    for i in range((bignumber+1)):
        if float(i)/bignumber in [float(count)/10 for count in range(11)]:
            yield i, float(i)/bignumber


class WorkerThread(QThread):
    progress = pyqtSignal(int)

    def run(self):
        it = someprocess()
        try:
            value, percentage = it.next()
            while value != None:
                value, percentage = it.next()
                self.progress.emit(percentage*100)
        except StopIteration:
            print "Completed!"
        except Exception, e:
            print "Unknown exception: ", repr(e)
            raise e

if __name__ == "__main__":
    it= someprocess()
    app = QApplication(sys.argv)
    mydialog = QDialog()
    myprogress = QProgressBar()
    mylabel = QLabel("Uninitiated.")
    mylayout = QVBoxLayout()
    mylayout.addWidget(mylabel)
    mylayout.addWidget(myprogress)
    mydialog.setLayout(mylayout)
    mydialog.show()
    w = WorkerThread()
    w.start()
    w.progress.connect(myprogress.setValue)
    sys.exit(app.exec_())