Quick User Interfaces with Qt
A consequence of Nokia's acquisition of Trolltech, a lot of attention has been paid to Qt's abilities in the mobile device space. This not only means speed optimizations and support for more platforms, such as Symbian (and Android, if you look at community efforts), but it also means that what the Nokians refer to as device user interfaces receive quite a lot of attention.
A device user interface is basically a look and feel that integrates well with the device on which it is used. It also provides what modern consumers expect: fluid transitions, graphical effects and a polished look. The consequence of this is a move from a widget-based user interface to a scene-based one.
Qt still supports widgets, and many, if not most, applications still use them. As a matter of fact, new user interfaces are run in a specific widget—QGraphicsView. QGraphicsView, in turn, shows a QGraphicsScene, which contains QGraphicsItem instances. All of this then is managed by Qt Quick.
The Qt Quick concept consists of two parts. The first is the QML language, used to build Qt Quick user interfaces. The other is the QtDeclarative module that provides the means to execute QML components and integrate them with C++ code.
The reason for developing QML was that creating fluid user interfaces with C++ is becoming increasingly complex. By designing a language specifically for the task of doing that, the work effort needed is greatly reduced. This is done in a fashion so that Qt and C++ still can be used for their strong points, by implementing the user interface using QML and the business logic and parts requiring performance in C++. As a side effect, the always-wanted split of user interface code and the rest of the application is enforced, as the parts are implemented using different languages.
To understand how Qt Quick can be used, let's look at three aspects. First, QML in general, then how QML is used to build dynamic user interfaces and finally, how QML and C++ fit together.
QML is a declarative language, based on JavaScript. It is based on the concepts of components that are declared and properties that are bound. A simple example of this is an empty, rectangular scene:
import Qt 4.7
Rectangle {
id: theRect
width: 400
height: width*1.5
}
In this snippet, the component Rectangle is instantiated. All words starting with an uppercase letter instantiate components. In the rectangle declaration, three properties are bound to values. The id property is special; it names items. In the future, the rectangle can be referenced as theRect. To access a property of the rectangle, such as its width, theRect.width can be used.
Next, the width is bound to the value 400, and the height is bound to the width times 1.5. Notice that the height is bound to width*1.5 and not assigned to the result of the multiplication. This means if the width changes, the height is updated automatically.
It also is worth noting the first line, which imports all components that are part of Qt version 4.7. This imports a set of components, such as the rectangle class, defined and implemented using C++. It is possible to import more C++-based components, components written in QML or entire modules of QML components.
I won't go into details on QML components here. Basically, a component is the contents of a given qml source file. Having imported a file named Foo.qml, its contents can be instantiated as Foo { ... }. A module is a directory containing components. Importing a module simply means importing all components of a directory. A really cool feature is that a module can be loaded from a remote location over the Internet.
One concept that is heavily integrated into QML is states and transitions between states. The Qt 4.6 release saw the introduction of the C++ classes for supporting this. However, with QML, using states and transitions is a natural thing.
The source code shown in Listing 1 demonstrates a number of QML concepts. First is the example of how to declare a hierarchy of items. The scene rectangle contains the red and blue rectangles. The red rectangle, in turn, contains a text item and a mouse area item.
Listing 1. States and Transitions
import Qt 4.7
Rectangle {
width: 300; height: 150
id: scene
Rectangle {
id: red
x: 50; y: 50
width: 50; height: 50
color: "red"
Text {
anchors.centerIn: parent
text: "Red"
}
MouseArea {
anchors.fill: parent
onClicked: {
if(scene.state == "redFocus")
scene.state="";
else
scene.state = "redFocus";
}
}
}
Rectangle {
id: blue
x: 200; y: 50
width: 50; height: 50
color: "blue"
MouseArea {
anchors.fill: parent
onClicked: {
if(scene.state == "blueFocus")
scene.state="";
else
scene.state = "blueFocus";
}
}
}
Text {
anchors.centerIn: blue
text: "Blue"
}
states: [
State {
name: "redFocus"
PropertyChanges { target: red; scale: 2.5 }
PropertyChanges { target: blue; rotation: 30 }
},
State {
name: "blueFocus"
PropertyChanges { target: red; rotation: 30 }
PropertyChanges { target: blue; scale: 2.5 }
}
]
transitions: [
Transition {
NumberAnimation { properties: "scale";
duration: 2000; easing.type: Easing.OutBounce }
NumberAnimation { properties: "rotation";
duration: 750; easing.type: Easing.InOutCubic }
}
]
}
The text item in the red rectangle demonstrates another feature: anchor layouts. Items can be anchored to each other, either to their sides or their center lines. The anchors can be offset using margins, and different items can be used for anchoring different parts of the same item. Basically, all your layout needs should be covered by anchor layouts. In this specific example, the center of the text is anchored to the center of the parent rectangle.
Further down, another text item is declared. This time, it is centered in the blue rectangle. Notice that the text item does not have to be a child of the item on which it is centered. This will have implications later on.
Moving on in the red rectangle, we reach the mouse area. This is another concept in QML—interactive areas are not mapped tightly to the visuals. A mouse area is used to interact with mouse events. Think of it as an invisible rectangle that can be anchored to other items, just as a visual item.
In the mouse area, the onClicked signal is bound to a piece of JavaScript. In this case, it alters the state property of the scene item. This brings us to the states and transitions.
Items in QML have a list of states and a list of transitions. In the example, the states' list contains two states: redFocus and blueFocus. Each state contains a number of PropertyChange items. These items modify properties of target items. In the case of redFocus, the scale of the red item and the rotation of the blue item are changed. Other items can be used in states—for instance, ParentChange moves items in the item hierarchy.
Looking back on the JavaScript bound to the onClicked event, the change of the state property moves between the states listed in the states property. When the state is set to an empty string, the default state is used. This means all properties are set to their initial, unaltered values.
The final piece of the puzzle is the transitions property, which is a list of behaviors for value changes of different properties. It is possible to control each individual property for each item for each transition direction. In the example, however, we control only each property for all items and all transitions. The NumberAnimation items control how long each change takes and how the change is made. The scale bounces while the rotation accelerates and decelerates according to a cubic curve, forming a smooth motion.
Looking at the screenshots in Figure 1, you can see the difference between the two texts. In the case of the red rectangle, the text is a child of the rectangle. This means the rotation and scaling of the rectangle is applied to the text too. In the case of the blue rectangle, the text simply stays centered. It is not affected by the transformations applied to the rectangle, because it is now a child of it.



Figure 1. States and Transitions
Johan Thelin is a consultant working with Qt, embedded and free software. On-line, he is known as e8johan.
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Designing Electronics with Linux | May 22, 2013 |
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
- Linux Systems Administrator
- New Products
- Senior Perl Developer
- Technical Support Rep
- UX Designer
- Web & UI Developer (JavaScript & j Query)
- Designing Electronics with Linux
- Dynamic DNS—an Object Lesson in Problem Solving
- Using Salt Stack and Vagrant for Drupal Development
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Featured Jobs
| Linux Systems Administrator | Houston and Austin, Texas | Host Gator |
| Senior Perl Developer | Austin, Texas | Host Gator |
| Technical Support Rep | Houston and Austin, Texas | Host Gator |
| UX Designer | Austin, Texas | Host Gator |
| Web & UI Developer (JavaScript & j Query) | Austin, Texas | Host Gator |
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?




1 hour 9 min ago
7 hours 1 min ago
11 hours 33 min ago
11 hours 33 min ago
13 hours 33 min ago
22 hours 19 min ago
22 hours 53 min ago
23 hours 51 min ago
1 day 42 min ago
1 day 4 hours ago