Qt Quick Timeline

A Look at the QtQuick Timeline Module

By Steve Holcomb

In the world of Qt, the QTimeline object is intended to help control animations. It is an object that acts somewhat like a timer: it has a duration and an interface for start/stop/resume functions. But a QTimeline object does more. It has a value that changes from beginning to end and has an update-interval that controls how often a valueChanged signal is emitted. It can run once or run in a loop.

One obvious usage of the QTimeline object is to control an animation in a GUI. Another usage could be to manage a variable that needs to have a particular range of values over a specified time.

The Qtimeline object does have drawbacks. Most notably, it is a C++ object so extra work needs to be done to expose it to the QML view. The object must be declared and managed in the world of C++, but also expose values to the QML environment.

How to Use QtQuick Timeline

Recently, a QtQuick-Timeline module was added to the Qt-5.14. This module has a Timeline object that can be created/managed inside a QML view. To use the QtQuick Timeline module, it’s necessary to install the Qt-5.14 release and select the package containing the QtQuick-Timeline module.

An example of a project that uses QtQuick Timeline can then be created. The easiest way to do this is to open QtCreator and create a new QtQuick application. In the main QML file for the application, the following import statements enable the use of QtQuick-Timeline:

import QtQuick 2.14
import QtQuick.Timeline 1.0

One simple example of QtQuick-Timeline is an animation that can move some rectangles around inside a QML view. For the purposes of this example, the rectangles can be declared as follows:

Rectangle {
  id: rect1
  x: 0
  y: 25
  width: 50
  height: 50
  color: "#800000"
}
Rectangle {
  id: rect2
  x: 0
  y: 125
  width: 50
  height: 50
  color: "#008000"
}

The Timeline object can be declared as follows:

Timeline {
  id: timeline
  startFrame: 0
  endFrame: 100

  animations: [
    TimelineAnimation {
      pingpong: true
      duration: 5000
      from: 0
      to: 100
      id: xPositionAnimation
    }
  ]
  keyframeGroups: [
    KeyframeGroup {
      target: rect1
      property: "x"
      Keyframe { frame: 0; value: 0 }
      Keyframe { frame: 50; value: 100 }
      Keyframe { frame: 100; value: 400 }
    },
    KeyframeGroup {
      target: rect2
      property: "x"
      Keyframe {frame: 0; value: 0 }
      Keyframe {frame: 50; value: 300 }
      Keyframe {frame: 100; value: 400 }
    }
}

Important values are 'startFrame' and 'endFrame', and an internal array 'animations' containing at least one TimelineAnimation. Each TimelineAnimation object has a 'duration' in milliseconds, and integer values for 'from' and 'to'. These values refer to frames in the Timeline that the TimelineAnimation begins at, and ends at. Optionally, each TimelineAnimation can have boolean value 'pingpong'.

Finally, the Timeline has an array called 'keyframeGroups'. Each entry in this array is a KeyframeGroup object. The KeyframeGroup objects each have a 'target' object, and a 'property' for that object. Each KeyframeGroup also has a list of Keyframe objects inside the KeyframeGroup. The Keyframe objects have 'frame' and 'value' pairs, which assign values to particular frames in the Timeline.

This example has three KeyframeGroup objects inside the array. These objects are for 'frame_0', 'frame_50', and 'frame_100' of the TimelineAnimation. One of these has a value changing from 0 to 100 to 400 across those frames, while the other has a value changing from 0 to 300 to 400 across the same frames.

When the TimelineAnimation is active, Timeline object will automatically create intermediate values for frames in between these Keyframes in the KeyframeGroup. By default, a linear approximation will be used for these intermediate values.

The example with two rectangles can be modified, so that the animation can be started (or stopped) by clicking one of the rectangles. 

Rectangle {
  id: rect1
  x: 0
  y: 25
  width: 50
  height: 50
  color: "#800000"
  <span style=" color:#800080;">MouseArea {
    </span><span style=" color:#800000;">anchors.fill</span>:<span style=" color:#c0c0c0;"> </span><span style=" font-style:italic;">parent</span>
<span style=" color:#800000;">    onClicked</span>:<span style=" color:#c0c0c0;"> </span>{
      <span style=" color:#808000;">if</span><span style=" color:#c0c0c0;"> </span>(<span style=" font-style:italic;">xPositionAnimation</span>.running)
<span style=" color:#c0c0c0;">        </span><span style=" font-style:italic;">xPositionAnimation</span>.stop();
      <span style=" color:#808000;">else</span>
<span style=" color:#c0c0c0;">        </span><span style=" font-style:italic;">xPositionAnimation</span>.start();
<span style=" color:#c0c0c0;">    </span>}
  }
}

Where to Find Example Code

The code seen above is available as part of this project. It creates an animation for the two rectangles in a QML view. It shows how to use a QML Timeline object inside QML, and how to avoid the need to create a C++ framework to link a QTimeline object to an animation in QML.

Links

Did you find this article helpful? Discover more great Qt/QML content here. 

Have a question or want to add to the conversation?

You must be logged in to continue.

Log in Register