본문 바로가기
Qt5 Python GUI Programming Cookbook

Implementing Animation

by 자동매매 2023. 2. 28.

In this chapter, you will learn how to apply motion to a given graphic image, hence implementing animation. Animations play a major role in explaining the practical workings of any machine, process, or system. In this chapter, we will be covering the following topics:

  • Displaying a 2D graphical picture
  • Making a ball move down on the click of a button
  • Making a bouncing ball
  • Making a ball animate as per the specified curve

Introduction

To view and manage 2D graphical items in Python, we need to make use of a class called QGraphicsScene. In order to display the contents of QGraphicsScene, we need the help of another class, called QGraphicsView. Basically, QGraphicsView provides a scrollable viewport to display the contents of QGraphicsScene. QGraphicsScene acts as a container for several graphical items. It also provides several standard shapes, such as rectangles and ellipses, including text items. One more thing: the QGraphicsScene uses OpenGL for rendering the graphics. The OpenGL is very efficient for displaying images and performing multimedia processing tasks. The QGraphicsScene class provides several methods that help in adding or removing graphical items from the scene. That is, you can add any graphical item to the scene by calling the addItem function. Similarly, to remove an item from the graphics scene, you can call the removeItem function.

Implementing animation

To apply animation in Python, we will be making use of the QPropertyAnimation class.

The QPropertyAnimation class in PyQt helps in creating and executing animations in PyQt. The QPropertyAnimation class implements animation by manipulating Qt properties such as a widget's geometry, position, and so on. The following are a few of the QPropertyAnimation methods:

  • start(): This method begins the animation
  • stop(): This method ends the animation
  • setStartValue(): This method is used to assign the starting value of the animation
  • setEndValue() animation
  • setDuration() milliseconds
  • setKeyValueAt()
  • setLoopCount() animation
  • This method is used to assign the ending value of the
  • This method is used to set the duration of the animation in
  • This method creates a keyframe at the given value
  • This method sets the count of the repetitions desired in the

Displaying a 2D graphical image

In this recipe, you will learn to display a 2D graphical image. We assume that you have a graphical image by the name scene.jpg on your machine, and you will learn how it is displayed on the form. The focus of this recipe is to understand how the Graphics View widget is used to display an image.

demoGraphicsView.py
0.00MB
demoGraphicsView.ui
0.00MB
scene.jpg
0.04MB

 

 

 

How to do it...

The procedure for displaying graphics is very simple. You first need to create an object of QGraphicsScene, which in turn makes use of the QGraphicsView class to show its contents. Graphical items, including images, are then added to the QGraphicsScene class by invoking the addItem method of the QGraphicsScene class. Here are the steps to display a 2D graphical image on the screen:

  1. Create a new application based on the Dialog without Buttons template.
  2. Drag and drop a Graphics View widget onto it.
  3. Save the application with the name demoGraphicsView.ui. The form will appear as shown in the following screenshot:

The pyuic5 command utility converts the .ui (XML) file into Python code. The generated Python script, demoGraphicsView.py, can be seen in the source code bundle of this book.

  1. Create a Python script named callGraphicsView.pyw that imports the code, demoGraphicsView.py, to invoke the user interface design, loads an image from the disk, and displays it through Graphics View. The Python script file, callGraphicsView.pyw, will include the following code:
import sys
from PyQt5.QtWidgets import QDialog, QApplication, QGraphicsScene, QGraphicsPixmapItem
from PyQt5.QtGui import QPixmap
from demoGraphicsView import *
class MyForm(QDialog):
    def __init__(self):
        super().__init__()
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        self.scene = QGraphicsScene(self)
        pixmap= QtGui.QPixmap()
        pixmap.load("scene.jpg")
        item=QGraphicsPixmapItem(pixmap)
        self.scene.addItem(item)
        self.ui.graphicsView.setScene(self.scene)
if __name__=="__main__":
    app = QApplication(sys.argv)
    myapp = MyForm()
    myapp.show()
    sys.exit(app.exec_())

 

How it works...

In this application, you are using Graphics View to display an image. You add a graphics scene to the Graphics View widget, and you add QGraphicsPixmapItem. If you want to add an image to the graphics scene, you need to provide it in the form of a pixmap item. First, you need to represent the image as pixmap, and then you make it appear as a pixmap item before adding it to the graphics scene. You need to create an instance of QPixmap and specify the image that you want to display through its load() method. Then, you tag the pixmap item as pixmapitem by passing pixmap to the constructor of QGraphicsPixmapItem. pixmapitem is then added to the scene via addItem. If pixmapitem is bigger than QGraphicsView, scrolling is enabled automatically.

In the previous code, I used an image with the filename scene.jpg. Please replace the filename with an image filename that is available on your disk, or nothing will be displayed on the screen.

The following methods are used:

  • QGraphicsView.setScene: This method (self, QGraphicsScene scene) assigns the scene that is supplied as a parameter to the GraphicView instance for display. If the scene is already being viewed, this function does nothing. When a scene is set on a view, the QGraphicsScene.changed signal is generated, and the view's scrollbars are adjusted to fit the size of the scene.
  • addItem: This method adds the specified item to the scene. If an item is already in a different scene, it will first be removed from its old scene and then added to the current scene. On running the application, the scene.jpg image will be displayed via the GrahicsView widget, as shown in the following screenshot:

Making a ball move down on the click of a button

In this recipe, you will understand how a basic animation is applied on an object. This recipe will consist of a push button and a ball, and when the push button is pressed, the ball will start animating towards the ground.

How to do it...

To make this recipe, we will be making use of the QPropertyAnimation class. The setStartValue() and setEndValue() methods of the QPropertyAnimation class will be used to define the coordinates where the animation needs to start and end, respectively. The setDuration() method will be invoked to specify the delay in milliseconds between every animation move. The following is the step-by-step procedure to apply an animation:

  1. Create a new application based on the Dialog without Buttons template.
  2. Drag and drop a Label widget and one Push Button widget onto the form.
  3. Set the text property of the Push Button widget to Move Down. We assume that you have a ball image on your computer with the filename coloredball.jpg.
  4. Select its pixmap property to assign the ball image to the Label widget.
  5. In the pixmap property, out of the two options, Choose Resource and Choose File, select the Choose File option, browse your disk, and select the coloredball.jpg file. The image of the ball will appear in place of the Label widget.
  6. Set the objectName property of the Push Button widget to pushButtonPushDown and that of the Label widget to labelPic.
  7. Save the application with the name demoAnimation1.ui. The application will appear as shown in the following screenshot:


The user interface created with Qt Designer is stored in a .ui file, which is an XML file that needs to be converted into Python code. On application of the pyuic5 command utility, the .ui file is converted into a Python script. The generated Python script, demoAnimation1.py, can be seen in the source code bundle of this book.

  1. Treat the demoAnimation1.py script as a header file, and import it into the file from which you will invoke its user interface design.
  2. Create another Python file with the name callAnimation1.pyw and import the demoAnimation1.py code into it:

How it works...

You can see that the click() event of the Push Button widget with the objectName property pushButtonMoveDown is connected to the startAnimation method; when the push button is clicked, the startAnimation method is invoked. In the startAnimation method, you create an object of the QPropertyAnimation class and name it anim. While creating the QPropertyAnimation instance, you pass two arguments;
the first is the Label widget to which you want to apply the animation and the second is the property that defines the object's attribute to which you want to apply the animation to the object's attribute. Because you want to apply an animation to the ball's geometry, you pass b"geometry" as the second attribute while defining the QPropertyAnimation object. After that, you specify the duration of the animation as 10000 milliseconds, meaning you want to change the geometry of the object after every 10,000 milliseconds. Through the setStartValue method, you specify the region that is the rectangular area where you want the animation to start, and by invoking the setEndValue method, you specify the rectangular region where you want to stop the animation. By invoking the start method, you initiate the animation; consequently, the ball moves down from the rectangular region specified through the setStartValue method until it reaches the rectangular region specified through the setEndValue method.

On running the application, you will find a push button and a Label widget representing the ball image on the screen, as shown in the following screenshot (left). On clicking the Move Down push button, the ball starts animating towards the ground and stop its animation at the region specified through the setEndValue method, as shown in the following screenshot (right):

Making a bouncing ball

In this recipe, you will make a bouncing ball; when clicking a button, a ball falls towards the ground and on touching the ground, it bounces back to the top. In this recipe, you will understand how a basic animation is applied on an object. This recipe will consist of a push button and a ball, and when the push button is pressed, the ball will start animating towards the ground.

How to do it...

To make a ball appear to be bouncing, we need to make it first animate towards the ground, and then from the ground up to the sky. To do so, we will be invoking the setKeyValueAt method of the QPropertyAnimation class three times. The first and second calls to the setKeyValueAt method will make the ball animate from the top to the bottom. The third call to the setKeyValueAt method will make the ball animate from bottom to top. The coordinates in the three setKeyValueAt methods are provided so that the ball bounces in the opposite direction, and not where it came from. The following are the steps to understand how a ball can be animated to appear to be bouncing:

  1. Create a new application based on the Dialog without Buttons template.
  2. Drag and drop a Label widget and one Push Button widget onto the form.
  3. Set the text property of the Push Button widget to Bounce. We assume that you have a ball image on your computer with the filename coloredball.jpg.
  4. To assign the ball image to the Label widget, select its pixmap property.
  5. In the pixmap property, out of the two options, Choose Resource and Choose File, select the Choose File option, browse your disk, and select the coloredball.jpg file. The image of the ball will appear in place of the Label widget.
  6. Set the objectName property of the Push Button widget to pushButtonBounce and that of the Label widget to labelPic.
  7. Save the application with the name demoAnimation3.ui.
    The application will appear as shown in the following screenshot:
    The user interface created with Qt Designer is stored in a .ui file, which is an XML file and needs to be converted into Python code. On application of the pyuic5 command utility, the .ui file is converted into a Python script. The generated Python script, demoAnimation3.py, can be seen in the source code bundle of this book.
  8. Treat the demoAnimation3.py script as a header file, and import it into the file from which you will invoke its user interface design.
  9. Create another Python file with the name callAnimation3.pyw and import the demoAnimation3.py code into it:

How it works...

You can see that the click() event of the Push Button widget with the objectName property, pushButtonMoveDown, is connected to the startAnimation method; when the push button is clicked, the startAnimation method will be invoked. In the startAnimation method, you create an object of the QPropertyAnimation class and name it anim. While creating the QPropertyAnimation instance, you pass two arguments:
the first is the Label widget to which you want to apply the animation, and the second is the property that defines the object's attribute to which you want to apply the animation to the object's attribute. Because you want to apply an animation to the ball's geometry, you pass b"geometry" as the second attribute while defining the QPropertyAnimation object. After that, you specify the duration of the animation as 10000 milliseconds, meaning you want to change the geometry of the object after every 10,000 milliseconds. Through the setKeyValue method, you specify the region that is the rectangular area where you want the animation to start. You mention the top-left region through this method because you want the ball to fall from the top-left corner towards the ground. Through the second call to the setKeyValue method, you supply the region in which you want the ball to fall to the ground. You also specify the angle of the fall. The ball will fall diagonally down towards the ground. By invoking the third setValue method, you specify the end value where you want the animation to stop, which in this case is in the top- right corner. Through these three calls to the setKeyValue method, you make the ball fall diagonally down towards the ground and then bounce back to the top-right corner. By invoking the start method, you initiate the animation.

On running the application, you will find the Push Button and Label widgets representing the ball image at the top-left corner of the screen, as shown in the following screenshot (left).

On clicking the Bounce push button, the ball starts animating diagonally down towards the ground, as shown in the middle screenshot, and after touching the ground, the ball bounces back towards the top-right corner of the screen, as shown on the right:

Making a ball animate as per the specified curve

A curve with the desired shape and size is created and a ball is set to move along the shape of the curve on the click of a push button. In this recipe, you will understand how to implement a guided animation.

How to do it...

The setKeyValueAt method of the QPropertyAnimation class determines the direction of an animation. For guided animation, you invoke the setKeyValueAt method in a loop. The coordinates of the curve are passed to the setKeyValueAt method in the loop to make the ball animate along the curve. Here are the steps to make an object animate as desired:

  1. Create a new application based on the Dialog without Buttons template.
  2. Drag and drop a Label widget and one Push Button widget onto the form.
  3. Set the text property of the Push Button widget to Move With Curve.
  4. Assuming you have a ball image on your computer with the filename coloredball.jpg, you can assign this ball image to the Label widget by using its pixmap property.
  5. In the pixmap property, you will find two options, Choose Resource and Choose File; select the Choose File option, browse your disk, and select the coloredball.jpg file. The image of the ball will appear in place of the Label widget.
  6. Set the objectName property of the Push Button widget to pushButtonMoveCurve and that of the Label widget to labelPic.
  7. Save the application with the name demoAnimation4.ui. The application will appear as shown in the following screenshot:
    The user interface created with Qt Designer is stored in a .ui file and is an XML file. The XML file is converted into Python code by applying the pyuic5 utility. You can find the generated Python code, demoAnimation4.py, in the source code bundle of this book.
  8. Treat the demoAnimation4.py script as a header file, and import it into the file from which you will invoke its user interface design.
  9. Create another Python file with the name callAnimation4.pyw and import the demoAnimation4.py code into it:

How it works...

First of all, you make the curve appear on the screen. This is the curve that will guide the ball's animation; that is, it will act as a path for the animation. You define an instance of the QPainterPath class and name it path. You invoke the moveTo method of the QPainterPath class to specify the starting location of the path or curve. The cubicTo method is invoked to specify the curved path for the ball's animation.
You can see that the click event of the Push Button widget with the objectName property pushButtonMoveCurve is connected to the startAnimation method; when the Push Button widget is clicked, the startAnimation() method will be invoked. In the startAnimation method, you create an object of the QPropertyAnimation class and name it anim. While creating the QPropertyAnimation instance, you pass two arguments: the first is the Label widget to which you want to apply the animation, and the second is the property that defines the object's attribute to which you want to apply the animation to the object's attribute. Because you want to apply the animation to the ball's position, you pass b'pos" as the second attribute while defining the QPropertyAnimation object. After that, you specify the duration of the animation as 4000 milliseconds, meaning you want to change the position of the ball after every 4000 milliseconds. Using the setStartValue() method of the QPropertyAnimation class, you specify the coordinates from where you want the ball to animate. You set the for loop that specifies the values that the ball needs to move along. You specify the path of the ball's animation by invoking the setKeyValue method inside the for loop. Because the ball needs to be drawn at every point specified in the path, you set the point where the ball needs to be drawn by invoking the pointAtPercent() method and passing it to the setKeyValueAt() method. You also need to set the location where the animation needs to stop by invoking the setEndValue() method.
Shortly after, you specify the start and end locations of the animation, you specify the path of animation, and the paintEvent() method is called to redraw the ball at every point of the path.

On running the application, you find the Push Button widget and a Label widget representing the ball image in the top-left corner of the screen (left side of the screenshot) and on clicking the Move With Curve push button, the ball starts animating along the drawn curve and stops where the curve ends (right side of the screenshot):

'Qt5 Python GUI Programming Cookbook' 카테고리의 다른 글

Running Python Scripts on Android and iOS  (0) 2023.02.28
Using Google Maps  (0) 2023.02.28
Using Graphics  (0) 2023.02.28
Database Handling  (0) 2023.02.28
Doing Asynchronous Programming in Python  (1) 2023.02.28

댓글