Обработка сигналов из C++ в коде QML

Последнее обновление: 06.01.2024

В C++ для взаимодействия с кодом QML можно использовать сигналы, слоты и функции Q_INVOKABLE. Например, пусть в проекте определен класс Counter, код которого состоит из заголовочного файла counter.h и файла с реализацией counter.cpp:

Связь сигналов и слотов в Qt и QML

В заголовочном файле counter.h определим следующий код:

#ifndef COUNTER_H
#define COUNTER_H

#include <QObject>

class Counter: public QObject
{
    Q_OBJECT
public:
    Counter(QObject *parent = nullptr){}

    Q_INVOKABLE void decrease();
    Q_INVOKABLE void increase();
signals:
    void valueChanged(int);
private:
    int value{};
};

#endif // COUNTER_H

Класс Counter наследуется от QObject и применяет макрос Q_OBJECT, благодаря чему класс может определять сигналы.

В классе определено приватное свойство value, в котором хранится некоторое значение объекта Counter. Также определено два метода - increase и decrease, которые будут изменять значение value. Благодаря макросу Q_INVOKABLE эти методы можно вызывать из кода QML.

И также определен сигнал valueChanged, который будет вызываться при изменении значения и через параметр которого будет передаваться новое значение.

В файле counter.cpp определим реализацию методов:

#include "counter.h"

void Counter::increase()
{
    value++;
    emit valueChanged(value);
}

void Counter::decrease()
{
    value--;
    emit valueChanged(value);
}

Методы увеличивают или уменьшают значение value на 1 и генерируют сигнал valueChanged, передавая в него обновленное значение.

В файле main.cpp зарегистрируем тип Counter:

#include <QGuiApplication>
#include <QQmlApplicationEngine>

#include "counter.h"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;

    // регистрация типа Counter
    qmlRegisterType<Counter>("counter", 1, 0,"Counter");

    const QUrl url("qrc:/path/main.qml");
    engine.load(url);
    return app.exec();
}

Используем тип Counter в файле main.qml:

import QtQuick
import QtQuick.Controls
import counter

Window {
    width: 250
    height: 150
    visible: true
    title: "METANIT.COM"

    function onValueChaged(newValue){
        labelCount.text = newValue;
    }
    Counter{ id: counter}
    Row{
        spacing: 10
        anchors.centerIn: parent
        Button {
            text: "+"
            width: 25
            height: 25
            onClicked: counter.increase()
        }
        Text{
            id: labelCount
        }
        Button {
            text: "-"
            width: 25
            height: 25
            onClicked: counter.decrease()
        }
    }
    Component.onCompleted: {
        counter.valueChanged.connect(onValueChaged)
    }
}

Здесь определен элемент Counter с идентификатором counter, с которым будут взаимодействовать другие элементы. В частности, здесь также определены две кнопки, по нажатию на которые будут вызываться методы increase и decrease объекта counter.

При завершении загрузки компонента окна устанавливаем для сигнала valueChanged объекта Counter в качестве обработчика функцию onValueChaged:

counter.valueChanged.connect(onValueChaged)

В этой функции получаем новое значение объекта Counter и устанавливаем его в качестве текста элемента labelCount:

function onValueChaged(newValue){
    labelCount.text = newValue;
}

Таким образом, при нажатии на кнопки произвойдет изменение значения в counter, и сработает событие valueChanged, которое будет обработано функцией onValueChaged:

Связь сигналов из класса на C++ с элементами в QML в Qt
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850