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

时间:2015-02-15 04:19:12

标签: python python-2.7 pyqt4 generator

我正在尝试使用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_())

有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

PyQt(或者一般来说,UI开发)通常需要将长时间运行函数放入后端线程,因此这不会阻塞您的UI线程,使其能够响应UI更新/用户交互。所以在这种情况下,你需要将“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_())