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