# Integrating with C++

## The C++

In order to demonstrate the connection between C++ and QML in Qt for MCUs, we will create a simple `Counter` singleton holding an integer value. Notice that we start from a `struct` and not a `class`. This is common practice in Qt Quick Ultralite.

The singleton will be used from a small UI as shown below.

![](https://378126997-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSh8Zb0vw9zlstTaGKIdC%2Fuploads%2Fgit-blob-b05585ba95183e58e2f4983c2c4f57b0d2654ac3%2Fcounter.png?alt=media)

The `Counter` struct provides a property, `value`, as well as methods for changing the value, `increase` and `decrease`, as well as a `reset` method. It also provides a signal, `hasBeenReset`.

```
#ifndef COUNTER_H
#define COUNTER_H

#include <qul/singleton.h>
#include <qul/property.h>
#include <qul/signal.h>

class Counter : public Qul::Singleton<Counter>
{
public:
    Counter();

    Qul::Property<int> value;

    void increase();
    void decrease();

    void reset();
    Qul::Signal<void(void)> hasBeenReset;

};

#endif // COUNTER_H
```

Coming from Qt, this looks odd. This is where Qt for MCUs shows the main differences. There is no `QObject` base class or `Q_OBJECT` macro, instead a new set of classes from the `Qul` is used. In this particular case, the base class is the `Qul::Singleton` class, creating a globally accessible singleton in the QML world. We also use the `Qul::Signal` class to create a signal and the `Qul::Property` class to create a property. All public, non-overloaded member functions are exposed to QML automatically.

{% hint style="info" %}
To create an element that can be instantiated from QML, instead of a singleton, use the \`Qul::Object\` base class.
{% endhint %}

The struct is then exposed to QML using the CMake macro `qul_target_generate_interfaces`. Below you can see the `CMakeLists.txt`, based on the file generated by Qt Creator, with the `counter.h` and `counter.cpp` files added.

```
qul_target_generate_interfaces(cppintegration counter.h)
```

Now, let's continue with the implementation of the `Counter` struct. First up, for the `value` property, we use the `value` and `setValue` functions to access and modify the actual value. In our case, the property holds and `int`, but just as for the ordinary QML engine, types are [mapped between C++ and QML](https://doc.qt.io/QtForMCUs/qtul-integratecppqml.html#type-mapping).

This is used in the constructor, shown below, that sets the initial value to zero.

```
Counter::Counter()
{
    value.setValue(0);
}
```

The `increase` and `decrease` functions look similar. They use the getter and setter instead of interacting directly with the value.

```
void Counter::increase()
{
    value.setValue(value.value()+1);
}

void Counter::decrease()
{
    value.setValue(value.value()-1);
}
```

`Counter` also has a signal. The signal is represented by the `Qul::Signal` instance named `hasReset`. The signal takes a function signature as template argument, so to create a signal carrying an integer, create a `Qul::Signal<void(int)>`. In this case, the signal does not carry any values, so it is defined as a `void(void)`. To emit the signal, we simply call it as if it was an ordinary function as shown in the `reset` function below.

```
void Counter::reset()
{
    std::cout << "Resetting from " << value.value() << std::endl;
    value.setValue(0);
    hasBeenReset();
}
```

## The QML

The QML code produces the simple user interface shown below.

![](https://378126997-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FSh8Zb0vw9zlstTaGKIdC%2Fuploads%2Fgit-blob-b05585ba95183e58e2f4983c2c4f57b0d2654ac3%2Fcounter.png?alt=media)

We will look at the UI in three parts. First, the basic structure, and bindings to `Counter.value`:

```
import QtQuick

Rectangle {
    width: 480
    height: 272

    Column {
        // Left buttons goes here
    }

    Column {
        // Right buttons goes here
    }

    Text {
        anchors.centerIn: parent
        text: Counter.value;
    }
}
```

As you can tell, the `Text` element's `text` property is bound to the `Counter.value` as in all QML.

Now, let's look at the left side buttons. These are used to invoke the C++ methods provided via the `Counter` singleton. The `PlainButton` is a QML element that we use to create these simple buttons. It lets you set the text, background color and a handler for the `clicked` signal. As you can tell, each button calls the corresponding method on the `Counter` singleton.

```
Column {
    x: 10
    y: 10
    spacing: 5
    PlainButton {
        text: "+"
        onClicked: Counter.increase()
    }
    PlainButton {
        text: "reset"
        onClicked: Counter.reset()
    }
    PlainButton {
        text: "-"
        onClicked: Counter.decrease()
    }
}
```

The buttons on the right modify the `Counter.value` directly from QML. This is possible to do, but invisible to C++. There is no simple way for C++ to monitor if a property has changed, so if a C++ reaction is needed, it is recommended to use a setter method, rather than directly modifying the property value.

```
Column {
    x: 350
    y: 10
    spacing: 5
    PlainButton {
        color: "orange"
        text: "++"
        onClicked: Counter.value += 5;
    }
    PlainButton {
        color: "orange"
        text: "100"
        onClicked: Counter.value = 100;
    }
    PlainButton {
        color: "orange"
        text: "--"
        onClicked: Counter.value -= 5;
    }
}
```

This shows how to provide a singleton from C++ and how to make function calls, emit signals, and share state (properties) between C++ and QML.

## Revisiting the CMake file

The `CMakeLists.txt` file may look familiar to you, but there are some tips and tricks that we need to discuss.

First of all, in order to expose a C++ class to QML, use the `qul_target_generate_interfaces`, e.g:

```
qul_target_generate_interfaces(cppintegration counter.h)
```

The other half, the QML files, are added using the `qul_target_qml_sources` macro. If you have multiple QML files, simply list them one by one as shown below:

```
qul_target_qml_sources(cppintegration cppintegration.qml PlainButton.qml)
```

Another interesting aspect is that we are building a C++ project without writing a `main` function. This is taken care of by the `app_target_default_main` macro that adds a reference main implementation to the project. You can of course replace this with a custom `main` function if you need more control.

```
app_target_default_main(cppintegration cppintegration)
```

Finally, the libraries linked to are not the standard Qt ones, but the `Qul::` ones, e.g:

```
target_link_libraries(cppintegration
    Qul::QuickUltralite
    Qul::QuickUltralitePlatform)
```

{% hint style="info" %}
Links Further reading at qt.io:

* [Integrate C++ and QML](https://doc.qt.io/QtForMCUs/qtul-integratecppqml.html)
  {% endhint %}
