# 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.

![](/files/XftTuzinWXkLuockRP1R)

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.

![](/files/XftTuzinWXkLuockRP1R)

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 %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.novaflowos.com/start/qt6-qml-book/readme/ch20-qtformcu/cpp.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
