Introduction
QML is the technology which allows you to create a platform-independent UI. The current Qt version 5.2 allows the creation of a single GUI which runs on Linux, Windows, OS X, iOS and Android without any changes on the code base. What i describe here is a CSS-like way to style QML controls and allows the reuse of these controls.
Background
The background of this article is a problem I encountered while developing the GUI study for the Workspaces::Tasks app: I wanted to use the Segoe UI font on all the text blocks, and be able to customize the background and foreground color of the said controls. In the end I ended up creating a QML file for each control I wanted to have a default style. So far I have defined the styles for the Rectangle and the Text control. This redefinitions are defined in CPRectangle.qml and CPText.qml.
These files need to be located at the same position as the main.qml in order to be used in the main window of the application. I have set up my development environment on OS X, but this doesn't make any difference because I use the Qt Creator that comes with Qt 5.2.1 - It's the same on every OS the Creator can run on. If you are interested in the outcome, it is the Splash screen of the GUI study.
I can't tell you anything more about what will come up with that study, since it is still under heavy development (And I still wonder about some specific control choices I need to make).
Customizing the Controls
First of all, I needed to have a Rectangle that comes in CodeProject Orange (#ff9900) to make the background of certain controls appear in a consistent way - Even though highly unlikely, Chris could decide to change the theme some day, and then I wish happy replacing if every control has the background color set manually. It was quite easy to do that, and what I did can be seen in the file CPRectangle.qml:
import QtQuick 2.0
Rectangle {
color:"#ff9900"
}
Everything I did was making a rectangle which has the color property set to CodeProject Orange (#ff9900). Because it is defined in CPRectangle.qml, the newly created control can be used within another QML file as CPRectangle, which I did when I defined CPText (in CPText.qml):
import QtQuick 2.0
CPRectangle{
Text {
id:textContent
font.family: "Segoe UI"
}
width: childrenRect.width
height: childrenRect.height
property alias text: textContent.text
property alias textColor: textContent.color
}
What has been done here is a bit more difficult, already. The CPText control is basically a CPRectangle containing an ordinary Text QML control which has set its font.family property to Segoe UI. I made the CPRectangle to automatically adjust itself to the size of the text by using childrenRect. width and childrenRect.height to define the width and height of the Rectangle. The difficult thing to do was to make certain properties of the Text control accessible by outside QML. The lines starting with property alias do the trick, e.g. property alias text: textContent.text allows me to access the text property of the inside Text control as in
CPText{
text: "CodeProject Workspaces::Tasks GUI study"
}
The same of course works with the textColor property.
Using the customized controls
Now we get to define the content of the main.qml file, which defines the main window (or in my case, the splash screen of the app). I used a row-and-colum orientated system to get QML to center the content of the window, and since this was kinda tricky, I also show it off here:
import QtQuick 2.0
CPRectangle {
id: rectangle1
width: 360
height: 360
Row{
anchors.centerIn: parent
Column{
anchors.centerIn: parent
BorderImage {
id: splash
width: 100
height: 100
source: "qrc:/logo/CPLogo.gif"
}
CPRectangle{
height:10
}
CPText{
anchors.topMargin: 1
text: "Workspaces::Tasks"
textColor:"White"
}
}
}
}
The background is a CPRectangle to have it in a nice CodeProject orange. Within this CPRectangle (given the very senseful name rectangle1) I have defined a single row which is my root node for every control placed on the screen. This row has a single column, which then contains a BorderImage which has set it's source property to display the CodeProject logo defined in the Resource file. Furthermore, there is another CPRectangle which is used as separator between picture and text. The text is the previously defined CPText which has set the textColor property alias to "White". To have everything nicely centered I have set the row and the column to be centered in their parent control.
Everything added up together gives us the following output:
User Interface on OS X
User Interface on Windows 7
Points of Interest
QML allows you to do a lot, and sometimes I think it adds additional complexity to the tasks you want to do. Nevertheless I think it is todays best and most-up-to-date multiplatform framework. I know that there is a really big rush about Mono and all that, yet Qt is much better documented and easier to extend than mono. And thanks to the C++ background code there is a really great chance that you can integrate existing legacy code withou needing to change a lot. QML has a pretty steep learning curvem but I see that it eases the more tutorials get published online. When I started out with Qt, information about QML was hard to find, but nowadays there are some really bright minds around on the net, bringing you the greatest tutorials to have you create something awesome with Qt. Sometimes the Javascript-like syntax of QML can be confusing, but the more you will use it, the more you will love it.