Изменение значения параметра объекта в QML из потока

171
28 ноября 2018, 18:00

Есть qml файл в котором нарисован датчик, содержимое примерно такое:

import QtQuick 2.2
import QtQuick.Window 2.1
Window
{
    visible: true
    id : mainScreen
    width: 720
    height: 400
    Rectangle
    {
        id : main_cadran
        anchors.fill: parent
        color : "black"
        Component.onCompleted: {
            forceActiveFocus();
        }
        visible: true
        property real speed_value : 0;

        Rectangle
        {
            id: top_line
            width : main_cadran.width
            height : main_cadran.height * 0.6
            color: "#000000"
            anchors
            {
                horizontalCenter : parent.horizontalCenter
                top : parent.top
            }
            RoundGauge
            {
                anchors
                {
                    left : top_line.left
                    right : top_line.horizontalCenter
                    top : top_line.top
                    bottom : top_line.bottom
                }
                unit: "value"
                currentValue: main_cadran.speed_value
                digitalFont.pointSize: 20
            }
        }

    }
}

У объекта RoundGauge есть свойство currentValue, отвечающее за текущее значение прибора.

На C++ создается поток с функцией обратного вызова, получающей данные с сервера. Задача состоит в том, чтобы эта функция обратого вызова могла корректировать значение currentValue в qml, меняя показания прибора. Подскажите, как это возможно реализовать. а лучше приведите пример подобной реализации. Спасибо!

Answer 1

Приведу пример реализации.

Класс dataOutput вырабатывает с заданной периодичностью сигнал (sigData(int)) с данными которые будем получать в QML.

dataOutput.h:

#ifndef DATAOUTPUT_H
#define DATAOUTPUT_H
#include <QObject>
#include <QTimer>
class DataOutput : public QObject
{
    Q_OBJECT
    int currentData;
    QTimer *timer;
public:
    DataOutput(QObject *parent = nullptr);
    ~DataOutput();
signals:
    void sigData(int currentdata);
private slots:
    void slTimeout();
};
#endif // DATAOUTPUT_H

dataOutput.cpp:

#include "dataoutput.h"
DataOutput::DataOutput(QObject *parent) : QObject(parent), currentData(0)
{
    timer = new QTimer();
    connect(timer, &QTimer::timeout, this, &DataOutput::slTimeout );
    timer->start(2000);
}
DataOutput::~DataOutput()
{
    timer->stop();
    if(timer != nullptr) delete timer;
}
void DataOutput::slTimeout()
{
    ++currentData;
    emit sigData(currentData);
    timer->start(2000);
}

Создаем QQmlContext которому указываем объект (DataOutput) к которому необходимо получить доступ из QML и задаём имя по которому будем к нему обращаться в QML.

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "dataoutput.h"
int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;
    QQmlContext *ctxt = engine.rootContext();
    DataOutput dataoutput;
    ctxt->setContextProperty("dataOutput", &dataoutput);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;
    return app.exec();
}

Теперь можно в QML получать сигнал от класса DataOutput. Для этого создаем соединение и обрабатываем полученный сигнал.

main.qml:

import QtQuick 2.9
import QtQuick.Window 2.2
Window {
    visible: true
    width: 640
    height: 480
    property real value: 0;
    Text {
        anchors.fill: parent
        horizontalAlignment: Text.AlignHCenter
        text: "Value: " + value
    }
    Connections {
        target: dataOutput
        onSigData: {
            value = currentdata;
        }
    }
}
READ ALSO
Помогите разобраться с заданием

Помогите разобраться с заданием

Вообщем вот задание

201
Есть альтернатива size(), только для массивов?

Есть альтернатива size(), только для массивов?

В функции array_print параметр arr является указателем на элемент массиваУзнать размер массива по указателю на его элемент невозможно

190
Возврат объекта из функции

Возврат объекта из функции

Вопрос по поводу вот такого случая:

190
Получение значения из шейдера

Получение значения из шейдера

Пусть имеется простые шейдера, образующие шейдерную программу:

173