On this page

C

Qt Quick Ultralite instrument_cluster Example

Demonstrates how to control user interface elements from a C application.

Overview

This example demonstrates how to control user interface elements from a C application.

Instrument_cluster example showing an automotive instrument cluster with a digital speedometer, trip meter, and blinker indicators.

Target platforms

Project structure

The instrument_cluster example consists of the following files:

  • src/VehicleStatus.cpp
  • src/VehicleStatus.h
  • CMakeLists.txt
  • instrument_cluster.qml

The CMake project file contains the build script and the project configuration, and instrument_cluster.qml defines the application's UI.

In addition to these files, the src/simulation folder contains a simple simulator to provide input data for the instrument cluster on non-AUTOSAR platforms:

  • src/simulation/baremetal/main.cpp
  • src/simulation/freertos/main.cpp
  • src/simulator.cpp
  • src/simulator.h

The fonts folder contains the font files of the application:

  • fonts/TitilliumWeb-Light.ttf
  • fonts/TitilliumWeb-SemiBold.ttf
CMake project file

Note: Simulation files are added only for non-AUTOSAR targets.

# Copyright (C) 2026 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial
cmake_minimum_required(VERSION 3.21.1)

project(instrument_cluster VERSION 0.0.1 LANGUAGES C CXX ASM)

find_package(QulApp)

if(QUL_PLATFORM MATCHES "^gerda-4")
    # Gerda platforms entrypoint function is same as baremetal
    set(QUL_OS_LOWERCASE "baremetal")
endif()

if(QUL_PLATFORM MATCHES "autosar")
    qul_add_library(instrument_cluster)
else()
    qul_add_executable(instrument_cluster)
endif()

qul_add_qml_module(instrument_cluster
    URI InstrumentClusterApp
    QML_FILES instrument_cluster.qml
    SOURCES
        src/VehicleStatus.cpp
        src/VehicleStatus.h
)

set_target_properties(instrument_cluster PROPERTIES
    QUL_DEFAULT_FONT_FAMILY "Titillium Web"
    QUL_FONT_FILES "${CMAKE_CURRENT_SOURCE_DIR}/fonts/TitilliumWeb-Light.ttf;${CMAKE_CURRENT_SOURCE_DIR}/fonts/TitilliumWeb-SemiBold.ttf"
)

target_include_directories(instrument_cluster PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)

# Every platform except autosar drives the UI from the bundled simulator and
# brings its own main(); autosar uses the generated entry point instead.
if(NOT QUL_PLATFORM MATCHES "autosar")
    target_sources(instrument_cluster PRIVATE
        src/simulation/simulator.cpp
        src/simulation/${QUL_OS_LOWERCASE}/main.cpp
    )
    target_include_directories(instrument_cluster PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/src/simulation
    )
endif()

app_target_setup_os(instrument_cluster)

if(QUL_PLATFORM MATCHES "autosar")
    app_target_default_entrypoint(instrument_cluster instrument_cluster MODULE InstrumentClusterApp)
endif()

if(NOT CMAKE_CROSSCOMPILING AND NOT WIN32)
    add_custom_command(TARGET instrument_cluster
        COMMAND strip instrument_cluster -o instrument_cluster.stripped
        DEPENDS instrument_cluster)
endif()
VehicleStatus singleton

The VehicleStatus singleton is responsible for storing the vehicle parameters for the user interface. It inherits from Qul::Singleton to expose the public signals and properties to QML.

    ...
    Qul::Property<int> speed;
    Qul::Property<double> tripMeter;
    Qul::Signal<void(bool leftBlinkerState)> leftBlinkerStateChange;
    Qul::Signal<void(bool rightBlinkerState)> rightBlinkerStateChange;
    ...

The QML code accesses these values via VehicleStatus singleton:

    ...
    Text {
        id: speedometer
        color: "#2CDE85"
        anchors.centerIn: parent

        font.weight: Font.DemiBold
        font.pixelSize: 90
        text: VehicleStatus.speed
    }
    ...

C linkage functions are exposed to the non-GUI code to control instrument cluster content:

...
extern "C" {
void qul_application_set_speed(int speed)
{
    VehicleStatus::instance().speed.setValue(speed);
}
...
AUTOSAR example

In an AUTOSAR project, the Qt Quick Ultralite Complex Device Driver calls the C linkage APIs as shown below:

#include "VehicleStatus.h"
...
// QUL Complex Device Driver Runnable with a periodic trigger
void Cdd_Qul_Update(void)
{
    static int previousSpeed = 0;
    int speed;

    // Read the speed value via the AUTOSAR Interface
    // Rte_Read_Cdd_Qul_Speed(&speed);

    if (speed != previousSpeed) {
        qul_application_set_speed(speed);
        previousSpeed = speed;
    }
    ...
    uint64 next_update = qul_update_engine(); // Calls Qul::Application::update()
    qul_wait_until(next_update);
}

Files:

See also Integrating C++ code with QML.

Available under certain Qt licenses.
Find out more.