QtWidgets.QProgressBar.setTextVisible(False) 导致滞后
QtWidgets.QProgressBar.setTextVisible(False) causes lag
我有一个每秒更新一次的 QProgressBar。它不需要百分比文本,所以我在创建它时添加了 progressBar.setTextVisible(False)
。然而,这使得它的响应速度极慢且滞后,因此更新时间超过一秒。另外,其他代码会等待进度条更新执行,导致整个程序变慢。这种情况发生在 macOS 上,其中进度条无论如何都不显示文本,而其他操作系统(如 Ubuntu)确实显示它。
为什么使进度文本不可见会导致此问题,我该如何解决(同时仍然删除进度文本)?
并不是说有延迟。为了便于理解,打个比方:假设有 2 个人,他们都必须在 1 秒内前进 1 米,但是第一个人每秒只做跳跃,而第二个人连续走几步,所以第一个人类似在没有文本的进度条和第二个有文本的进度条上。
当progressbar的值改变时,判断是否需要重新绘制,在有可见文字的情况下,无论如何都要重新绘制,但如果值改变则不需要重新绘制, 另一方面,如果除了更改的值之外没有其他文本,则要求该步骤是适当的我认为出于性能原因。
那部分代码可以在下面找到link
解决办法是每次有变化就强制绘画
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_())
我有一个每秒更新一次的 QProgressBar。它不需要百分比文本,所以我在创建它时添加了 progressBar.setTextVisible(False)
。然而,这使得它的响应速度极慢且滞后,因此更新时间超过一秒。另外,其他代码会等待进度条更新执行,导致整个程序变慢。这种情况发生在 macOS 上,其中进度条无论如何都不显示文本,而其他操作系统(如 Ubuntu)确实显示它。
为什么使进度文本不可见会导致此问题,我该如何解决(同时仍然删除进度文本)?
并不是说有延迟。为了便于理解,打个比方:假设有 2 个人,他们都必须在 1 秒内前进 1 米,但是第一个人每秒只做跳跃,而第二个人连续走几步,所以第一个人类似在没有文本的进度条和第二个有文本的进度条上。
当progressbar的值改变时,判断是否需要重新绘制,在有可见文字的情况下,无论如何都要重新绘制,但如果值改变则不需要重新绘制, 另一方面,如果除了更改的值之外没有其他文本,则要求该步骤是适当的我认为出于性能原因。
那部分代码可以在下面找到link
解决办法是每次有变化就强制绘画
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_())