我正在尝试使用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_())
有更好的方法吗?
答案 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_())