我有一个QProgressBar,它每秒更新一次。它不需要百分比文本,所以我在创建它时添加了progressBar.setTextVisible(False)
。然而,这使得它的响应速度极慢且滞后,因此更新需要一秒钟以上的时间。此外,其他代码会等待进度条更新以执行,从而使整个程序速度变慢。这种情况既发生在macOS上,进度条无论如何都不会显示文本,也发生在其他操作系统上,比如Ubuntu,会显示文本
为什么进度文本不可见会导致这种情况,以及我如何解决这个问题(同时仍然删除进度文本(?
这并不是说存在滞后。为了让你更好地理解它,可以用下面的比喻:假设有两个人,他们都必须在1秒内前进1米,但第一个人每秒只跳一次,而第二个人则连续走几步,所以第一个人在没有文本的进度条和有文本的第二个人是相似的。
当进度条的值发生变化时,会评估是否有必要重新绘制它,在有可见文本的情况下,无论如何都会这样做,尽管如果值发生了变化,则不需要这样做;另一方面,如果除了变化的值之外没有其他文本,则需要该步骤是合适的,我认为出于性能的原因。
该部分代码可以在以下链接中找到
解决方法是每次出现更改时都强制绘制。
progressBar.valueChanged.connect(progressBar.repaint)
示例:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
def create_progressBar(timeLine, isTextVisible, workaround=False):
progressBar = QtWidgets.QProgressBar()
progressBar.setTextVisible(isTextVisible)
timeLine.frameChanged.connect(progressBar.setValue)
if workaround:
progressBar.valueChanged.connect(progressBar.repaint)
progressBar.setRange(0, 100)
return progressBar
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
widget = QtWidgets.QWidget()
lay = QtWidgets.QFormLayout(widget)
timeLine = QtCore.QTimeLine(1000*10)
timeLine.setFrameRange(0, 100)
normal_with_text = create_progressBar(timeLine, True)
normal_without_text = create_progressBar(timeLine, False)
workaround_without_text = create_progressBar(timeLine, False, True)
lay.addRow("normal_with_text", normal_with_text)
lay.addRow("normal_without_text", normal_without_text)
lay.addRow("workaround_without_text", workaround_without_text)
timeLine.start()
widget.show()
sys.exit(app.exec_())