Объект QML не обновляется на дисплее

Я создал объект QML на С++. В моем основном методе я могу установить различные свойства, которые я определил в своем пользовательском объекте QML. При установке из основного метода различные свойства отображаются, как и ожидалось. Когда я устанавливаю свойства из своего метода обновления, отображение никогда не обновляется. Я проверил, что связанные методы в моем пользовательском объекте QML получают значения, которые я ему передаю. Почему мой дисплей не обновляется?

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "horizontalBarGraph.h"
#include "speedometer.h"
#include "test.h"
#include <QTimer>
#include <QDebug>

//QObject *item = NULL;
static HorizontalBarGraph *ptrOilTemp = nullptr;
static int value = 0;


int update()
{
    //qInfo() << "update() called.";


    if (value > ptrOilTemp->getMaxValue())
    {
        value = 0;
    }
    ptrOilTemp->setActualValue(value);
    qInfo() << "value = " << value;

    value++;

    //ptrOilTemp->setUnits("Test");

    return 0;
}

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    qmlRegisterType<Speedometer>("com.ulasdikme.speedometer",1,0,"Speedometer");
    qmlRegisterType<HorizontalBarGraph>("com.kubie.horizontalBarGraph", 1, 0, "HorizontalBarGraph");
    qmlRegisterType<Test>("com.kubie.test", 1, 0, "Test");

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    //item = engine.rootObjects().at(0)->findChild<QQuickItem*>("testing");

    QObject *object = engine.rootObjects()[0];
    QObject *oilTemp = object->findChild<QObject*>("oilTemp");
    QObject *oilPressure = object->findChild<QObject*>("oilPressure");
    QObject *coolantTemp = object->findChild<QObject*>("coolantTemp");
    QObject *coolantPressure = object->findChild<QObject*>("coolantPressure");
    QObject *intakeAirTemp = object->findChild<QObject*>("intakeAirTemp");
    QObject *engineRPM = object->findChild<QObject*>("engineRPM");

    //HorizontalBarGraph *ptrOilTemp = qobject_cast<HorizontalBarGraph*>(oilTemp);
    ptrOilTemp = qobject_cast<HorizontalBarGraph*>(oilTemp);
    HorizontalBarGraph *ptrOilPressure = qobject_cast<HorizontalBarGraph*>(oilPressure);
    HorizontalBarGraph *ptrCoolantTemp = qobject_cast<HorizontalBarGraph*>(coolantTemp);
    HorizontalBarGraph *ptrCoolantPressure = qobject_cast<HorizontalBarGraph*>(coolantPressure);
    HorizontalBarGraph *ptrIntakeAirTemp = qobject_cast<HorizontalBarGraph*>(intakeAirTemp);
    HorizontalBarGraph *ptrEngineRPM = qobject_cast<HorizontalBarGraph*>(engineRPM);

    qreal val1 = 0;
    //qreal val2 = 25;
    qreal val3 = 100;

    QString degF(QChar(0x00b0));
    degF += "F";

    ptrOilTemp->setSensorName("Oil Temp");
    ptrOilTemp->setUnits(degF);
    ptrOilTemp->setMinValue(val1);
    ptrOilTemp->setMaxValue(val3);
    //ptrOilTemp->setActualValue(val2);

    ptrOilPressure->setSensorName("Oil Press");
    ptrOilPressure->setUnits("PSI");

    ptrCoolantTemp->setSensorName("Coolant Temp");
    ptrCoolantTemp->setUnits(degF);

    ptrCoolantPressure->setSensorName("Coolant Press");
    ptrCoolantPressure->setUnits("PSI");

    ptrIntakeAirTemp->setSensorName("Intake Air Temp");
    ptrIntakeAirTemp->setUnits(degF);

    ptrEngineRPM->setSensorName("");
    ptrEngineRPM->setUnits("RPM");

    qInfo() << "Initializing timer.";
    QTimer timer;// = new QTimer(this);
    QObject::connect(&timer, &QTimer::timeout, update);
    timer.start(100);



    return app.exec();
}

HorizontalBarGraph.cpp

#include <QPainter>
#include "horizontalBarGraph.h"

HorizontalBarGraph::HorizontalBarGraph(QQuickItem *parent)
    :QQuickPaintedItem(parent),
      _horizontalBarGraphWidth(260),
      _horizontalBarGraphHeight(75),
      _minValue(0),
      _maxValue(0),
      _actualValue(0),
      _sensorName("Sensor Name"),
      _units("Units")
{

}

void HorizontalBarGraph::paint(QPainter *painter)
{
    QRectF rect = this->boundingRect();
    painter->setRenderHint(QPainter::Antialiasing);
    QPen pen = painter->pen();
    pen.setCapStyle(Qt::FlatCap);

    QFont bottomFont("Arial", 14, QFont::Bold);
    QFont topFont("Arial", 16, QFont::Bold);
    QColor gray1(225, 225, 225);
    QColor gray2(200, 200, 200);
    QColor gray3(175, 175, 175);
    QColor gray4(100, 100, 100);

    //minValue, actualValue, maxValue
    painter->save();
    painter->setFont(bottomFont);
    pen.setColor(gray1);
    painter->setPen(pen);
    painter->drawText(rect.adjusted(0, 50, -210, 0), Qt::AlignHCenter | Qt::AlignBottom, QString::number((_minValue), 'f', 0)); //Draws minValue
    painter->drawText(rect.adjusted(210, 50, 0, 0), Qt::AlignHCenter | Qt::AlignBottom, QString::number((_maxValue), 'f', 0)); //Draws maxValue
    painter->drawText(rect.adjusted(0, 50, 0, 0), Qt::AlignHCenter | Qt::AlignBottom, QString::number((_actualValue), 'f', 1));
    //pen.setStyle(Qt::DotLine); //Next 3 lines were used to show the bounding rectangle for a drawText object
    //painter->setPen(pen);
    //painter->drawRect(rect.adjusted(0, 50, -150, 0));
    painter->restore();

    //Bar chart background
    painter->save();
    painter->fillRect(rect.adjusted(25, 35, -25, -25), gray1);
    painter->restore();

    //Lo
    painter->save();
    painter->fillRect(rect.adjusted(25, 35, -185, -25), gray2);
    painter->restore();

    //LoLo
    painter->save();
    painter->fillRect(rect.adjusted(25, 35, -210, -25), gray3);
    painter->restore();

    //Hi
    painter->save();
    painter->fillRect(rect.adjusted(185, 35, -25, -25), gray2);
    painter->restore();

    //HiHi
    painter->save();
    painter->fillRect(rect.adjusted(210, 35, -25, -25), gray3);
    painter->restore();

    //Sensor name, Units
    painter->save();
    painter->setFont(topFont);
    pen.setColor(gray1);
    painter->setPen(pen);
    painter->drawText(rect.adjusted(25, 0, -50, -40), Qt::AlignLeft | Qt::AlignTop, _sensorName); //Draws sensor name
    painter->drawText(rect.adjusted(50, 0, -25, -40), Qt::AlignRight | Qt::AlignTop, _units); //Draws units
    painter->restore();

    //Arrow
//    painter->save();
//    static const QPointF points[3] = {
//        QPointF(17.5, 27.5),
//        QPointF(32.5, 27.5),
//        QPointF(25.0, 42.5)
//    };
//    painter->drawPolygon(points, 3);
//    painter->restore();
    painter->save();
    QPainterPath path;
    qreal x = scale(_actualValue, _minValue, _maxValue, 25, 235);
    //path.moveTo(17.5, 27.5);
    //path.lineTo(32.5, 27.5);
    //path.lineTo(25.0, 42.5);
    path.moveTo(x - 7.5, 27.5);
    path.lineTo(x + 7.5, 27.5);
    path.lineTo(x, 42.5);
    path.closeSubpath();
    painter->fillPath(path, gray4);
    painter->restore();


}


qreal HorizontalBarGraph::getHorizontalBarGraphWidth()
{
    return _horizontalBarGraphWidth;
}


qreal HorizontalBarGraph::getHorizontalBarGraphHeight()
{
    return _horizontalBarGraphHeight;
}


qreal HorizontalBarGraph::getMinValue()
{
    return _minValue;
}


qreal HorizontalBarGraph::getMaxValue()
{
    return _maxValue;
}


qreal HorizontalBarGraph::getActualValue()
{
    return _actualValue;
}


QString HorizontalBarGraph::getSensorName()
{
    return _sensorName;
}


QString HorizontalBarGraph::getUnits()
{
    return _units;
}


void HorizontalBarGraph::setHorizontalBarGraphWidth(qreal width)
{
    if (_horizontalBarGraphWidth == width)
        return;

    _horizontalBarGraphWidth = width;

    emit widthChanged();
}


void HorizontalBarGraph::setHorizontalBarGraphHeight(qreal height)
{
    if (_horizontalBarGraphHeight == height)
        return;

    _horizontalBarGraphHeight = height;

    emit heightChanged();
}


void HorizontalBarGraph::setMinValue(qreal minValue)
{
    if (_minValue == minValue)
        return;

    _minValue = minValue;

    emit minValueChanged();
}


void HorizontalBarGraph::setMaxValue(qreal maxValue)
{
    if (_maxValue == maxValue)
        return;

    _maxValue = maxValue;

    emit maxValueChanged();
}


void HorizontalBarGraph::setActualValue(qreal actualValue)
{
    if (_actualValue == actualValue)
        return;

    _actualValue = actualValue;

    emit actualValueChanged();
}


void HorizontalBarGraph::setSensorName(QString sensorName)
{
    if (_sensorName == sensorName)
        return;

    _sensorName = sensorName;

    emit sensorNameChanged();
}


void HorizontalBarGraph::setUnits(QString units)
{
    if (_units == units)
        return;

    _units = units;

    emit unitsChanged();
}


qreal HorizontalBarGraph::scale(qreal input, qreal inputMin, qreal inputMax, qreal outputMin, qreal outputMax)
{
    qreal output = (outputMax - outputMin) * (input - inputMin) / (inputMax - inputMin) + outputMin;
    if (output > outputMax)
        output = outputMax;

    if (output < outputMin)
        output = outputMin;

    return output;
}

HorizontalBarGraph.h

#ifndef HORIZONTALBARGRAPH_H
#define HORIZONTALBARGRAPH_H

#include <QObject>
#include <QQuickPaintedItem>

class HorizontalBarGraph : public QQuickPaintedItem
{
    Q_OBJECT

    Q_PROPERTY(qreal horizontalBarGraphWidth READ getHorizontalBarGraphWidth WRITE setHorizontalBarGraphWidth NOTIFY horizontalBarGraphWidthChanged)
    Q_PROPERTY(qreal horizontalBarGraphHeight READ getHorizontalBarGraphHeight WRITE setHorizontalBarGraphHeight NOTIFY horizontalBarGraphHeightChanged)
    Q_PROPERTY(qreal minValue READ getMinValue WRITE setMinValue NOTIFY minValueChanged)
    Q_PROPERTY(qreal maxValue READ getMaxValue WRITE setMaxValue NOTIFY maxValueChanged)
    Q_PROPERTY(qreal actualValue READ getActualValue WRITE setActualValue NOTIFY actualValueChanged)
    Q_PROPERTY(QString sensorName READ getSensorName WRITE setSensorName NOTIFY sensorNameChanged)
    Q_PROPERTY(QString units READ getUnits WRITE setUnits NOTIFY unitsChanged)


public:
    HorizontalBarGraph(QQuickItem *parent = 0);
    virtual void paint(QPainter *painter);

    qreal   getHorizontalBarGraphWidth();
    qreal   getHorizontalBarGraphHeight();
    qreal   getMinValue();
    qreal   getMaxValue();
    qreal   getActualValue();
    QString getSensorName();
    QString getUnits();

    void    setHorizontalBarGraphWidth(qreal width);
    void    setHorizontalBarGraphHeight(qreal height);
    void    setMinValue(qreal minValue);
    void    setMaxValue(qreal maxValue);
    void    setActualValue(qreal actualValue);
    void    setSensorName(QString sensorName);
    void    setUnits(QString units);

signals:
    void    horizontalBarGraphWidthChanged();
    void    horizontalBarGraphHeightChanged();
    void    minValueChanged();
    void    maxValueChanged();
    void    actualValueChanged();
    void    sensorNameChanged();
    void    unitsChanged();

private:
    qreal   _horizontalBarGraphWidth;
    qreal   _horizontalBarGraphHeight;
    qreal   _minValue;
    qreal   _maxValue;
    qreal   _actualValue;
    QString _sensorName;
    QString _units;
    qreal   scale(qreal input, qreal inputMin, qreal inputMax, qreal outputMin, qreal outputMax);

};

#endif // HORIZONTALBARGRAPH_H

main.qml

import QtQuick 2.11
import QtQuick.Window 2.11
import com.kubie.horizontalBarGraph 1.0

Window {
    id: window
    visible: true
    width: 800
    height: 480
    title: qsTr("REDNEKSLDHLR")
    color: "black"

//    Rectangle
//    {
//        width: 260
//        height: 75
//        color: "#7a0505"
//        anchors.bottom: parent.bottom
//        anchors.bottomMargin: 0
//        anchors.left: parent.left
//        anchors.leftMargin: 0
//    }

    HorizontalBarGraph {
        objectName: "oilTemp"
        anchors.left: parent.left
        anchors.leftMargin: 0
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 0
        width: horizontalBarGraphWidth
        height: horizontalBarGraphHeight
    }

    HorizontalBarGraph {
        objectName: "oilPressure"
        anchors.left: parent.left
        anchors.leftMargin: 0
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 75
        width: horizontalBarGraphWidth
        height: horizontalBarGraphHeight
    }

    HorizontalBarGraph {
        objectName: "coolantTemp"
        anchors.right: parent.right
        anchors.rightMargin: 0
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 0
        width: horizontalBarGraphWidth
        height: horizontalBarGraphHeight
    }

    HorizontalBarGraph {
        objectName: "coolantPressure"
        anchors.right: parent.right
        anchors.rightMargin: 0
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 75
        width: horizontalBarGraphWidth
        height: horizontalBarGraphHeight
    }

    HorizontalBarGraph {
        objectName: "intakeAirTemp"
        anchors.left: parent.left
        anchors.leftMargin: parent.width / 2 - width / 2;
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 0
        width: horizontalBarGraphWidth
        height: horizontalBarGraphHeight
    }

        HorizontalBarGraph {
            objectName: "engineRPM"
            anchors.left: parent.left
            anchors.leftMargin: parent.width / 2 - width / 2;
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 75
            width: horizontalBarGraphWidth
            height: horizontalBarGraphHeight
    }


}

пожалуйста, предоставьте минимальный воспроизводимый пример. Где приложение QGui?

eyllanesc 22.12.2020 23:13

Сообщение @eyllanesc было обновлено, чтобы включить весь код.

kubiej21 22.12.2020 23:22

Вот и все... Примеры, которым я следовал, никогда не вызывали обновление, что мне показалось немного странным. Хотя я никогда не складывал два и два. Можете ли вы опубликовать в качестве ответа, и я приму его?

kubiej21 22.12.2020 23:26
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
226
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы должны использовать метод update(), чтобы графический интерфейс перерисовывался, поэтому вы должны вызывать его каждый раз, когда изменяется свойство, которое используется для рисования. Например:

void HorizontalBarGraph::setActualValue(qreal actualValue) {     
    if (_actualValue == actualValue)         
        return;      
    _actualValue = actualValue;     
    update();  
    emit actualValueChanged(); 
}

Другие вопросы по теме