This tutorial is contributed by Martin, one of our customers:
Learning to build game with Felgo is really easy thanks to the great tutorials and example games that are available in full source.
However, from time to time a programmer needs some fundamentals of how the language constructs work – a foundation to help extend the examples.
QML itself is very well documented, at length, at qt.io. But sometimes you just want a snapshot to get you going. Here are the things I found useful to know.
We are very happy to put this contribution to our documentation, filling some gaps in the basic understanding of QML and its syntax. If you found a documentation online that helped you, or even wrote something on your own, contact us so we can share it with other developers.
In QML, each object is declared in a file, with the file name being the class name.
The file SubClass.qml
import Felgo 4.0 import QtQuick 2.0 BaseClass { // … specialisation }
declares a SubClass derived from a BaseClass ...
... it doesn’t declare a BaseClass, as you might first think, looking at the contents of the file.
Programming with QML involves defining and describing attributes of the objects.
QML objects have the following types of attributes:
id
attribute (unique)Additionally to those attributes, you can add child objects, creating a QML tree.
The QML objects that you use in Felgo are generally derived from the Item base class – this is the base class for all visual objects (objects that can, but not necessarily have to, be displayed).
In the development of a Felgo app, Item objects are usually declared and then specialised in the following ways:
Here's an example containing several of those specialisations: LabelBox.qml
import Felgo 4.0 import QtQuick 2.0 Rectangle { id: labelBox // adding a new property property int padding: 5 // adding a new property by making the text property of the textItem publicly accessible property alias label: textItem.text // modify property of Rectangle color: "red" width: textItem.width + (padding * 2) height: textItem.height + (padding * 2) // add a child object Text { id: textItem anchors.centerIn: labelBox //anchors.centerIn: parent // this would also work, thanks to the QML tree } }
A property of an object can be a basic type (such as the integer padding
in the example above), or it can be an alias of one of its children’s properties, to expose them to instantiating or deriving objects
(again as show in the example above).
Note: An object deriving from a base can only access the properties of the base, not the internals of the base directly.
In the example above you can also see another important feature of the QML language, which is the id
attribute. This attribute allows an object to be accessed, in order to access its properties and children. In
the example above, the textItem
refers to the labelBox
to get centered, and the property alias refers to the textItem
.
The scope of an id
is the component scope in which it is declared – that is the current QML file and all its children.
This means that you can safely instantiate several LabelBox
es and give the instances each an id
, like this:
import Felgo 4.0 import QtQuick 2.0 Item { LabelBox { id: label1 label: "Test1" } LabelBox { id: label2 label: "Test321" padding: 10 anchors.top: label1.bottom } Item { id: some_item } }
Note that is is also possible to refer to id
s at the instantiating level from within instantiated components in the object tree. For example, within the definition of LabelBox
you could refer to
some_item
. Clearly, doing this would make LabelBox
much less re-useable: it would mean that a component instantiating LabelBox
must have an object with id
some_item
.
There are some times in a Felgo app where this makes sense – all Felgo apps have a GameWindow, for example, and probably they all have an EntityManager, so you will often see these top-level components referred to by their id
.
There are many use cases where you want to execute some logic after an object has been created. This is where in many languages the Constructor comes in handy. The QML "equivalent" is the
Component.onCompleted
attached signal handler.
It does provide the opportunity to run javascript after the object is constructed, which is what you often need. Here an example:
LabelBox.qml
import Felgo 4.0 import QtQuick 2.0 Rectangle { id: labelBox // ... Component.onCompleted: { console.debug("LabelBox has been constructed") } }
Also have a look at these other short QML Language Tutorials:
Go through these essential tutorials that help you learning QML & Felgo, by making simple games:
Visit Felgo Games Examples and Demos to gain more information about game creation with Felgo and to learn from the source code of existing apps in the app stores.
Finally we gathered some very useful links from the Qt documentation, which have a closer look at the topics that we just covered: