I have a custom progress bar that I would like to animate as it changes from one value to another. When I get a value, I repaint the rectangle which represents the progress bar - so I think this should be as simple as animating the value itself and redrawing on each change. I've been looking through the Animation Framework documentation and I"m pretty sure subclassing a QVariantAnimation
will do what I need - but there are little to no Python examples that I can find, and I'm a bit lost.
Here's where I've got so far (please excuse me if this is way off):
import sys
from PyQt4 import QtGui, QtCore
class AnimateBetweenNums(QtCore.QVariantAnimation):
def __init__(self):
QtCore.QVariantAnimation.__init__(self)
def updateCurrentValue(self, value):
print value.toString()
class MyProgressbar(QtGui.QWidget):
def __init__(self):
super(MyProgressbar, self).__init__()
self.initUI()
def initUI(self):
self.setMinimumSize(2, 2)
self.value = 50
def setValue(self, value):
oldValue = 10
newValue = 70
anim = AnimateBetweenNums()
anim.setStartValue(oldValue)
anim.setEndValue(newValue)
anim.setDuration(1000)
anim.start()
anim.valueChanged.connect(self.updateValue)
def updateValue(self, value):
self.value = value
self.repaint()
def paintEvent(self, e):
qp = QtGui.QPainter()
qp.begin(self)
self.drawWidget(qp)
qp.end()
def drawWidget(self, qp):
size = self.size()
w = size.width()
h = size.height()
till = int(((w / 100.0) * self.value))
#the bar
qp.setPen(QtGui.QColor(255, 255, 255))
qp.setBrush(QtGui.QColor(0, 228, 47))
qp.drawRect(0, 0, till, h)
#the box
pen = QtGui.QPen(QtGui.QColor(75,80,100), 1, QtCore.Qt.SolidLine)
qp.setPen(pen)
qp.setBrush(QtCore.Qt.NoBrush)
qp.drawRect(0, 0, w - 1, h - 1)
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
hbox = QtGui.QVBoxLayout()
self.button10 = QtGui.QPushButton("10")
hbox.addWidget(self.button10)
self.button70 = QtGui.QPushButton("70")
hbox.addWidget(self.button70)
self.progress = MyProgressbar()
hbox.addWidget(self.progress)
self.setLayout(hbox)
self.setGeometry(300, 300, 390, 210)
self.show()
self.button10.clicked.connect(self.changeValue10)
self.button70.clicked.connect(self.changeValue70)
def changeValue10(self, value):
self.progress.setValue(10)
self.progress.repaint()
def changeValue70(self, value):
self.progress.setValue(70)
self.progress.repaint()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Below is a re-written version of your script that hopefully does what you intended. The animation object should only be created once, and because you are using Python 2 with PyQt4, you need to make sure any QVariant
values are converted correctly. I also changed the setValue()
method so that it restarts from the previous value.
import sys
from PyQt4 import QtGui, QtCore
class AnimateBetweenNums(QtCore.QVariantAnimation):
def __init__(self):
QtCore.QVariantAnimation.__init__(self)
def updateCurrentValue(self, value):
print value.toString()
class MyProgressbar(QtGui.QWidget):
def __init__(self):
super(MyProgressbar, self).__init__()
self.initUI()
def initUI(self):
self.setMinimumSize(2, 2)
self.anim = AnimateBetweenNums()
self.anim.setDuration(1000)
self.anim.valueChanged.connect(self.updateValue)
self.value = 50
def setValue(self, value):
self.anim.setStartValue(self.value)
self.anim.setEndValue(value)
self.anim.start()
def updateValue(self, value):
self.value = QtCore.QVariant(value).toInt()[0]
self.repaint()
def paintEvent(self, e):
qp = QtGui.QPainter()
qp.begin(self)
self.drawWidget(qp)
qp.end()
def drawWidget(self, qp):
size = self.size()
w = size.width()
h = size.height()
till = int(((w / 100.0) * self.value))
#the bar
qp.setPen(QtGui.QColor(255, 255, 255))
qp.setBrush(QtGui.QColor(0, 228, 47))
qp.drawRect(0, 0, till, h)
#the box
pen = QtGui.QPen(QtGui.QColor(75,80,100), 1, QtCore.Qt.SolidLine)
qp.setPen(pen)
qp.setBrush(QtCore.Qt.NoBrush)
qp.drawRect(0, 0, w - 1, h - 1)
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
hbox = QtGui.QVBoxLayout()
self.button10 = QtGui.QPushButton("10")
hbox.addWidget(self.button10)
self.button70 = QtGui.QPushButton("70")
hbox.addWidget(self.button70)
self.progress = MyProgressbar()
hbox.addWidget(self.progress)
self.setLayout(hbox)
self.setGeometry(300, 300, 390, 210)
self.show()
self.button10.clicked.connect(self.changeValue10)
self.button70.clicked.connect(self.changeValue70)
def changeValue10(self, value):
self.progress.setValue(10)
def changeValue70(self, value):
self.progress.setValue(70)
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()