Reputation: 39
I have drawn a rectangle on QWidget
after clicking push button rectangle moves from "LEFT TOP CORNER" to "RIGHT TOP CORNER"
How to move rectangle:
from PyQt5.QtWidgets import QWidget, QApplication, QFrame, QPushButton
from PyQt5.QtCore import QPropertyAnimation, QRect
from PyQt5.QtGui import QFont
import sys
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("Animation Window")
self.setGeometry(100, 100, 400, 400)
self.widgets()
self.show()
def widgets(self):
font = QFont("Times New Roman")
font.setPixelSize(20)
self.start = QPushButton("Start", self)
self.start.setFont(font)
self.start.setGeometry(100, 100, 100, 50)
self.start.clicked.connect(self.doAnimation)
self.frame = QFrame(self)
self.frame.setStyleSheet("background-color:darkGreen;")
self.frame.setFrameStyle(QFrame.Panel | QFrame.Raised)
self.frame.setGeometry(250, 100, 100, 100)
def doAnimation(self):
self.anim = QPropertyAnimation(self.frame, b"geometry")
self.anim.setDuration(10000)
self.anim.setStartValue(QRect(0, 0, 100, 100))
self.anim.setEndValue(QRect(1366, 0, 100, 100))
self.anim.start()
if __name__ == "__main__":
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
Upvotes: 1
Views: 288
Reputation: 243897
Although using the finished
signal is interesting, a more compact and scalable method is to use QSequentialAnimationGroup
where you can concatenate animations that will run sequentially.
from PyQt5 import QtCore, QtGui, QtWidgets
class Example(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("Animation Window")
self.setGeometry(100, 100, 400, 400)
self.widgets()
self.show()
def widgets(self):
font = QtGui.QFont("Times New Roman")
font.setPixelSize(20)
self.start = QtWidgets.QPushButton("Start", self)
self.start.setFont(font)
self.start.setGeometry(100, 100, 100, 50)
# self.start.clicked.connect(self.doAnimation)
self.frame = QtWidgets.QFrame(self)
self.frame.setStyleSheet("background-color:darkGreen;")
self.frame.setFrameStyle(QtWidgets.QFrame.Panel | QtWidgets.QFrame.Raised)
self.frame.setGeometry(250, 100, 100, 100)
r = self.frame.rect()
rects = []
r.moveTopLeft(self.rect().topLeft())
rects.append(QtCore.QRect(r))
r.moveTopRight(self.rect().topRight())
rects.append(QtCore.QRect(r))
r.moveBottomRight(self.rect().bottomRight())
rects.append(QtCore.QRect(r))
r.moveBottomLeft(self.rect().bottomLeft())
rects.append(QtCore.QRect(r))
r.moveTopLeft(self.rect().topLeft())
rects.append(QtCore.QRect(r))
sequential_animation = QtCore.QSequentialAnimationGroup(self, loopCount=-1)
for rect_start, rect_end in zip(rects[:-1], rects[1:]):
animation = QtCore.QPropertyAnimation(
targetObject=self.frame,
propertyName=b"geometry",
startValue=rect_start,
endValue=rect_end,
duration=1000,
)
sequential_animation.addAnimation(animation)
self.start.clicked.connect(sequential_animation.start)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Example()
sys.exit(app.exec())
Upvotes: 2
Reputation: 142631
You can use signal to run next animation when first is finished
self.anim.finished.connect(self.doAnimation_2)
This code moves rectangle all time - last animation starts first animation.
from PyQt5.QtWidgets import QWidget, QApplication, QFrame, QPushButton
from PyQt5.QtCore import QPropertyAnimation, QRect
from PyQt5.QtGui import QFont
import sys
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("Animation Window")
self.setGeometry(100, 100, 400, 400)
self.widgets()
self.show()
def widgets(self):
font = QFont("Times New Roman")
font.setPixelSize(20)
self.start = QPushButton("Start", self)
self.start.setFont(font)
self.start.setGeometry(100, 100, 100, 50)
self.start.clicked.connect(self.doAnimation_1)
self.frame = QFrame(self)
self.frame.setStyleSheet("background-color:darkGreen;")
self.frame.setFrameStyle(QFrame.Panel | QFrame.Raised)
self.frame.setGeometry(250, 100, 100, 100)
def doAnimation_1(self):
self.anim = QPropertyAnimation(self.frame, b"geometry")
self.anim.setDuration(1000)
self.anim.setStartValue(QRect(0, 0, 100, 100))
self.anim.setEndValue(QRect(300, 0, 100, 100))
self.anim.finished.connect(self.doAnimation_2)
self.anim.start()
def doAnimation_2(self):
self.anim = QPropertyAnimation(self.frame, b"geometry")
self.anim.setDuration(1000)
self.anim.setStartValue(QRect(300, 0, 100, 100))
self.anim.setEndValue(QRect(300, 300, 100, 100))
self.anim.finished.connect(self.doAnimation_3)
self.anim.start()
def doAnimation_3(self):
self.anim = QPropertyAnimation(self.frame, b"geometry")
self.anim.setDuration(1000)
self.anim.setStartValue(QRect(300, 300, 100, 100))
self.anim.setEndValue(QRect(0, 300, 100, 100))
self.anim.finished.connect(self.doAnimation_4)
self.anim.start()
def doAnimation_4(self):
self.anim = QPropertyAnimation(self.frame, b"geometry")
self.anim.setDuration(1000)
self.anim.setStartValue(QRect(0, 300, 100, 100))
self.anim.setEndValue(QRect(0, 0, 100, 100))
self.anim.finished.connect(self.doAnimation_1)
self.anim.start()
if __name__ == "__main__":
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
If you will have to run different animations in different moments then probably you could use QTimer
Upvotes: 0