Deepak Bhargav
Deepak Bhargav

Reputation: 39

Rectangle moving

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

Answers (2)

eyllanesc
eyllanesc

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

furas
furas

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

Related Questions