Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Exposing C++ values to QML issue
Forum Updated to NodeBB v4.3 + New Features

Exposing C++ values to QML issue

Scheduled Pinned Locked Moved Solved General and Desktop
16 Posts 4 Posters 703 Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    Thanni123
    wrote on last edited by
    #1

    Hello guys,

    I have some strange issues with my actual project i'm sitting on. Maybe some of you could help me :) I've already read some blogs but unfortunately none of them could help me.
    Actually the issue should be quite easy but I didn't get my mistake. I want to send the value of my AlertMessage class to the QML and display it. That's all. Unfortunately, I'm getting weird float values instead of the right double values.
    Here are my classes. It would be awesome if someone could help me :D

    main.cpp

    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
    
        Subscriber subber(targetDir, "");
    
        qmlRegisterType<AlertMessage>("io.qt.alertmessage", 1, 0, "AlertMessage");
    
        QQmlApplicationEngine engine;
        engine.load(QUrl(QStringLiteral("PassengerUI/HeadUnit.qml")));
        qDebug() << "--- Passenger UI started ---";
    
        return app.exec();
    }
    

    To be more precise I've created an instance of my Subscriber class ('subber' above) which initiate an instance of my MessageHandler class ('m_handler' below) calling another class to read some local json files. At the end I'm storing my collected information in an instance of my AlertMessage class which then should be sent to my qml.

    subscriber.cpp

    void Subscriber::readFromJsonFile(QString filePath)
    {
        if (filePath.isEmpty())
        {
            filePath = QDir::currentPath();
        }
    
        QString useCase;
        QFile file;
        file.setFileName(filePath + "/sub_message.json");
        file.open(QIODevice::ReadOnly | QIODevice::Text);
        useCase = file.readAll();
        file.close();
    
        QJsonDocument useCaseDoc = QJsonDocument::fromJson(useCase.toUtf8());
        QJsonObject useCaseObj = useCaseDoc.object();
        m_handler->processReceivedMessages(useCaseObj);
    }
    

    messagehandler.cpp

    void MessageHandler::processReceivedMessages(QJsonObject jsonObject)
    {
        m_alertMessage->readDataFromJSONFormat(jsonObject);
        qDebug() << m_alertMessage->printout();
    }
    

    alertmessage.h

    #ifndef ALERTMESSAGE_H
    #define ALERTMESSAGE_H
    
    #include <QString>
    #include <QJsonObject>
    #include <QObject>
    
    class AlertMessage : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(QString messageType      READ messageType        WRITE setMessageType        NOTIFY messageTypeChanged)
        Q_PROPERTY(QString sender           READ sender             WRITE setSender             NOTIFY senderChanged)
        Q_PROPERTY(QString alertType        READ alertType          WRITE setAlertType          NOTIFY alertTypeChanged)
        Q_PROPERTY(QString id               READ id                 WRITE setID                 NOTIFY idChanged)
        Q_PROPERTY(QString origin           READ origin             WRITE setOrigin             NOTIFY originChanged)
        Q_PROPERTY(QString dataSource       READ dataSource         WRITE setDataSource         NOTIFY dataSourceChanged)
        Q_PROPERTY(double distanceToEvent   READ distanceToEvent    WRITE setDistanceToEvent    NOTIFY distanceToEventChanged)
        Q_PROPERTY(double severity          READ severity           WRITE setSeverity           NOTIFY severityChanged)
        Q_PROPERTY(double azimuth           READ azimuth            WRITE setAzimuth            NOTIFY azimuthChanged)
        Q_PROPERTY(double timeToEvent       READ timeToEvent        WRITE setTimeToEvent        NOTIFY timeToEventChanged)
        Q_PROPERTY(int detailLevel          READ detailLevel        WRITE setDetailLevel        NOTIFY detailLevelChanged)
    
    public:
        explicit AlertMessage(QObject *parent = nullptr);
        AlertMessage(QJsonObject &jsonObject);
        AlertMessage(std::string &JsonInfo);
    
        void cleanMessage();
    
        void readDataFromJSONFormat(QJsonObject &jsonObject);
        void readDataFromJSONFormat(std::string &json);
    
        QString messageType() const;
        void setMessageType(const QString &messageType);
    
        QString sender() const;
        void setSender(const QString &sender);
    
        QString alertType() const;
        void setAlertType(const QString &alertType);
    
        QString id() const;
        void setID(const QString &id);
    
        QString origin() const;
        void setOrigin(const QString &origin);
    
        QString dataSource() const;
        void setDataSource(const QString &dataSource);
    
        double distanceToEvent() const;
        void setDistanceToEvent(const double &distance);
    
        double severity() const;
        void setSeverity(const double &severity);
    
        double azimuth() const;
        void setAzimuth(const double &azimuth);
    
        double timeToEvent() const;
        void setTimeToEvent(const double &time);
    
        int detailLevel() const;
        void setDetailLevel(const int &level);
    
        void setAlertReceived(const bool &fcw, const bool &rww, const bool &eebl);
    
        QString printout();
    
    signals:
        void messageTypeChanged();
        void senderChanged();
        void alertTypeChanged();
        void idChanged();
        void originChanged();
        void dataSourceChanged();
        void distanceToEventChanged();
        void severityChanged();
        void azimuthChanged();
        void timeToEventChanged();
        void detailLevelChanged();
    
    private:
    
        QString m_messageType;
        QString m_sender;
        QString m_alertType;
        QString m_id;
        QString m_origin;
        QString m_dataSource;
        double m_distanceToEvent;
        double m_severity;
        double m_azimuth;
        double m_timeToEvent;
        int m_detailLevel;
    
        bool m_fcwAvailable;
        bool m_rwwAvailable;
        bool m_eeblAvailable;
    };
    
    #endif // ALERTMESSAGE_H
    
    

    alertmessage.cpp

    #include <QJsonObject>
    #include <QJsonDocument>
    #include <QDebug>
    
    #include "alertmessage.h"
    
    AlertMessage::AlertMessage(QObject *parent) :
        QObject(parent)
    {
    }
    
    AlertMessage::AlertMessage(QJsonObject &jsonObject):
        AlertMessage()
    {
        readDataFromJSONFormat(jsonObject);
    }
    
    AlertMessage::~AlertMessage()
    {
        cleanMessage();
    }
    
    void AlertMessage::cleanMessage()
    {
        m_messageType = "";
        m_sender = "";
        m_alertType = "";
        m_id = "";
        m_origin = "";
        m_dataSource = "";
    
        m_distanceToEvent = 0;
        m_severity = 0;
        m_azimuth = 0;
        m_timeToEvent = 0;
        m_detailLevel = 0;
        m_fcwAvailable = false;
        m_rwwAvailable = false;
        m_eeblAvailable = false;
    }
    
    void AlertMessage::readDataFromJSONFormat(QJsonObject &jsonObject)
    {
        if (jsonObject.count() <= 0)
        {
            qDebug() << "AlertMessage::Wrong JSON-Array.";
            return;
        }
        cleanMessage();
    
        setMessageType(jsonObject["type"].toString());
        setSender(jsonObject["sender"].toString());
    
        QJsonValue valueData = jsonObject.value(QString("data"));
        QJsonObject dataObject = valueData.toObject();
    
        if (!dataObject.isEmpty())
        {
            setAlertType(dataObject["alert"].toString());
            setID(dataObject["id"].toString());
            setOrigin(dataObject["origin"].toString());
            setDataSource(dataObject["data_source"].toString());
            setDistanceToEvent(dataObject["distance_to_event"].toDouble());
            setSeverity(dataObject["severity"].toDouble());
            setAzimuth(dataObject["azimuth"].toDouble());
            setTimeToEvent(dataObject["time_to_event"].toDouble());
    
            QJsonValue detailValue = dataObject.value(QString("detail"));
            QJsonObject detailObject = detailValue.toObject();
    
            if (!detailObject.isEmpty())
            {
                 setDetailLevel(detailObject["level"].toInt());
            }
        }
    }
    
    QString AlertMessage::messageType() const
    {
        return m_messageType;
    }
    
    void AlertMessage::setMessageType(const QString &messageType)
    {
        if (m_messageType != messageType)
        {
            m_messageType = messageType;
            emit messageTypeChanged();
        }
        return;
    }
    
    

    Do not wonder. I've created for every variable an own getter and setter method like above. I posted only one example to keep my post clear :D
    On the C++ side everything seems to work fine. The data was stored successful to my alertmessage instance. I've debugged the values and got this.
    "** AlertMessage begin**\nMessageType = ALERT\nSender = \nAlertType = FCW\nID = \nOrigin = Cohda_TA\nDataSource = \nDistance_To_Event = 55.2\nSeverity = 9\nAzimuth = 25.5434\nTime_To_Event = 20.3\nDetailLevel = 0\nFCWAvailable = 0\nRWWAvailable = 0\nEEBLAvailable = 0\n** AlertMessage end **\n"

    But on the QML side there are some strange output:
    qml: QML:1.6911919422062236e-306, ... and so on.

    I hope you can help me.

    Best regards,
    Thanni

    1 Reply Last reply
    0
    • Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by Christian Ehrlicher
      #2

      Since you don't initialize your members I would guess "if (!dataObject.isEmpty())" is false so your values will not be set so you see the uninitialized data in your qml

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      1 Reply Last reply
      1
      • T Offline
        T Offline
        Thanni123
        wrote on last edited by
        #3

        No, I just checked the value. dataObject is not empty and it will execute the setter methods.

        1 Reply Last reply
        0
        • Christian EhrlicherC Offline
          Christian EhrlicherC Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Please properly initialize the members in the ctor and see if the 'strange' values disappear.

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          1 Reply Last reply
          1
          • T Offline
            T Offline
            Thanni123
            wrote on last edited by
            #5

            I initialized all members but I still didn't get any values displayed on the qml side ...

            AlertMessage::AlertMessage(QObject *parent) :
                QObject(parent),
                m_messageType(""),
                m_sender(""),
                m_alertType(""),
                m_id(""),
                m_origin(""),
                m_dataSource(""),
                m_distanceToEvent(0),
                m_severity(0),
                m_azimuth(0),
                m_timeToEvent(0)
            {
            }
            
            Christian EhrlicherC 1 Reply Last reply
            0
            • fcarneyF Offline
              fcarneyF Offline
              fcarney
              wrote on last edited by
              #6

              QML, what QML? Please show the QML. Preferably a minimally compileable example.

              C++ is a perfectly valid school of magic.

              1 Reply Last reply
              0
              • T Offline
                T Offline
                Thanni123
                wrote on last edited by
                #7

                Here is a snippet of my QML code

                import QtQuick 2.0
                import io.qt.alertmessage 1.0
                
                import "../BasicItems"
                import "../ModellingItems"
                
                import "../../WarningCalc.js" as WarningCalcer
                
                Rectangle
                {
                    id: informationCellArea
                
                    property int informationTextHeaderSize: 10
                    property int informationTextSize: 17
                    property int itemHeight: parent.height/4
                    property int headerToTextMargin: 10
                
                    property string senderString
                    property string distanceString
                    property string timeString
                    property string descriptionString
                    property string trafficSignString
                    property int severityInt
                
                    color: "transparent"
                    radius: 10
                
                    AlertMessage
                    {
                        id: alertMessage
                    }
                
                    Item
                    {
                        id: distanceArea
                        width: parent.width/2
                        height: itemHeight
                        anchors.left: parent.left
                        anchors.bottom: descriptionUseCaseArea.top
                
                        HMIText
                        {
                            id: distanceTextHeader
                            text: "Distance to event"
                            fontSize: informationTextHeaderSize
                            anchors.centerIn: parent
                        }
                
                        HMIText
                        {
                            id: distanceText
                            text:  alertMessage.distanceToEvent + " m"
                            fontSize: informationTextSize
                            useFontBold: true
                            anchors.top: distanceTextHeader.bottom
                            anchors.topMargin: headerToTextMargin
                            anchors.horizontalCenter: parent.horizontalCenter
                
                            onTextChanged: {
                                console.log("QML:" + distanceString);
                            }
                        }
                    }
                }
                
                
                1 Reply Last reply
                0
                • T Thanni123

                  I initialized all members but I still didn't get any values displayed on the qml side ...

                  AlertMessage::AlertMessage(QObject *parent) :
                      QObject(parent),
                      m_messageType(""),
                      m_sender(""),
                      m_alertType(""),
                      m_id(""),
                      m_origin(""),
                      m_dataSource(""),
                      m_distanceToEvent(0),
                      m_severity(0),
                      m_azimuth(0),
                      m_timeToEvent(0)
                  {
                  }
                  
                  Christian EhrlicherC Offline
                  Christian EhrlicherC Offline
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on last edited by Christian Ehrlicher
                  #8

                  @Thanni123 said in Exposing C++ values to QML issue:

                  get any values displayed on the qml side ...

                  You don't see any double value or you don't see the strange values anymore? Please initialize one string to something other than an empty string.

                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                  Visit the Qt Academy at https://academy.qt.io/catalog

                  1 Reply Last reply
                  0
                  • fcarneyF Offline
                    fcarneyF Offline
                    fcarney
                    wrote on last edited by
                    #9

                    What is in readDataFromJSONFormat and printout?
                    So far I cannot see any real issues.

                    C++ is a perfectly valid school of magic.

                    T 1 Reply Last reply
                    0
                    • T Offline
                      T Offline
                      Thanni123
                      wrote on last edited by
                      #10

                      Well if I'm initializing the constructor with some default value, it display the value I've created. But if I try to set the values with the json file the value mentioned above appear or the value equals 0.

                      1 Reply Last reply
                      0
                      • fcarneyF fcarney

                        What is in readDataFromJSONFormat and printout?
                        So far I cannot see any real issues.

                        T Offline
                        T Offline
                        Thanni123
                        wrote on last edited by
                        #11

                        @fcarney I've posted the method declaration above and the printout method is only a debug method to display if the values were set.

                        I think I did a mistake during initializing an object of my AlertMessage class but I didn't get my fault yet... It must be some stupid mistake I've done.

                        1 Reply Last reply
                        0
                        • fcarneyF Offline
                          fcarneyF Offline
                          fcarney
                          wrote on last edited by
                          #12

                          @Thanni123 said in Exposing C++ values to QML issue:

                          But if I try to set the values with the json file the value mentioned above appear or the value equals 0.

                          The problem is in readDataFromJSONFormat and/or printout. If you want help you need to show what is in those. So far nothing you have posted shows any problems.

                          C++ is a perfectly valid school of magic.

                          1 Reply Last reply
                          0
                          • T Offline
                            T Offline
                            Thanni123
                            wrote on last edited by
                            #13

                            Hey, I don't get your point exactly but here is the source code of your request for both methods including the output for the printout mehtod.

                            void AlertMessage::readDataFromJSONFormat(const QJsonObject &jsonObject)
                            {
                                if (jsonObject.count() <= 0)
                                {
                                    qDebug() << "AlertMessage::Wrong JSON-Array.";
                                    return;
                                }
                                cleanMessage();
                            
                                setMessageType(jsonObject["type"].toString());
                                setSender(jsonObject["sender"].toString());
                            
                                QJsonValue valueData = jsonObject.value(QString("data"));
                                QJsonObject dataObject = valueData.toObject();
                            
                                if (!dataObject.isEmpty())
                                {
                                    setAlertType(dataObject["alert"].toString());
                                    setID(dataObject["id"].toString());
                                    setOrigin(dataObject["origin"].toString());
                                    setDataSource(dataObject["data_source"].toString());
                                    setDistanceToEvent(dataObject["distance_to_event"].toDouble());
                                    setSeverity(dataObject["severity"].toDouble());
                                    setAzimuth(dataObject["azimuth"].toDouble());
                                    setTimeToEvent(dataObject["time_to_event"].toDouble());
                            
                                    QJsonValue detailValue = dataObject.value(QString("detail"));
                                    QJsonObject detailObject = detailValue.toObject();
                            
                                    if (!detailObject.isEmpty())
                                    {
                                         setDetailLevel(detailObject["level"].toInt());
                                    }
                                }
                            }
                            
                            QString AlertMessage::printout()
                            {
                                QString print = "** AlertMessage begin**\n";
                                print += "MessageType       = " + QString("%1").arg(this->messageType()) + "\n";
                                print += "Sender            = " + QString("%1").arg(this->sender()) + "\n";
                                print += "AlertType         = " + QString("%1").arg(this->alertType()) + "\n";
                                print += "ID                = " + QString("%1").arg(this->id()) + "\n";
                                print += "Origin            = " + QString("%1").arg(this->origin()) + "\n";
                                print += "DataSource        = " + QString("%1").arg(this->dataSource()) + "\n";
                                print += "Distance_To_Event = " + QString("%1").arg(this->distanceToEvent()) + "\n";
                                print += "Severity          = " + QString("%1").arg(this->severity()) + "\n";
                                print += "Azimuth           = " + QString("%1").arg(this->azimuth()) + "\n";
                                print += "Time_To_Event     = " + QString("%1").arg(this->timeToEvent()) + "\n";
                                print += "DetailLevel       = " + QString("%1").arg(this->detailLevel()) + "\n";
                                print += "FCWAvailable      = " + QString("%1").arg(this->fcwReceived()) + "\n";
                                print += "RWWAvailable      = " + QString("%1").arg(this->rwwReceived()) + "\n";
                                print += "EEBLAvailable     = " + QString("%1").arg(this->eeblReceived()) + "\n";
                            
                                print += "** AlertMessage end **\n";
                            
                                return print;
                            }
                            

                            The output for my printout method:

                            QDateTime(2020-02-18 00:15:02.786 Mitteleuropäische Zeit Qt::LocalTime)
                            "** AlertMessage begin**\nMessageType       = ALERT\nSender            = \nAlertType         = FCW\nID                = \nOrigin            = Cohda_TA\nDataSource        = \nDistance_To_Event = 55.2\nSeverity          = 9\nAzimuth           = 25.5434\nTime_To_Event     = 20.3\nDetailLevel       = 0\nFCWAvailable      = 0\nRWWAvailable      = 0\nEEBLAvailable     = 0\n** AlertMessage end **\n"
                            

                            Hope this helps somehow :)

                            1 Reply Last reply
                            0
                            • fcarneyF Offline
                              fcarneyF Offline
                              fcarney
                              wrote on last edited by
                              #14

                              I cannot see anything wrong in this code. All I can think is do a make clean, qmake, make project and see if this gets any better. I don't see any variables such as references exceeding their lifetime or anything. Sorry I cannot be more helpful. This should just work.

                              C++ is a perfectly valid school of magic.

                              1 Reply Last reply
                              0
                              • T Offline
                                T Offline
                                Thanni123
                                wrote on last edited by
                                #15

                                I think I figured out the issue but I don't know how to solve it. It's relying on this call in the main.cpp.

                                main.cpp

                                qmlRegisterType<AlertMessage>("io.qt.alertmessage", 1, 0, "AlertMessage");
                                

                                This method uses the standard constructor of my AlertMessage class without the QJsonObject as a parameter. I need to define my custom constructor but I get stuck with some errors ...
                                If I don't use my custom constructor it will always initiliaze without any values set.

                                KroMignonK 1 Reply Last reply
                                0
                                • T Thanni123

                                  I think I figured out the issue but I don't know how to solve it. It's relying on this call in the main.cpp.

                                  main.cpp

                                  qmlRegisterType<AlertMessage>("io.qt.alertmessage", 1, 0, "AlertMessage");
                                  

                                  This method uses the standard constructor of my AlertMessage class without the QJsonObject as a parameter. I need to define my custom constructor but I get stuck with some errors ...
                                  If I don't use my custom constructor it will always initiliaze without any values set.

                                  KroMignonK Offline
                                  KroMignonK Offline
                                  KroMignon
                                  wrote on last edited by
                                  #16

                                  @Thanni123 said in Exposing C++ values to QML issue:

                                  If I don't use my custom constructor it will always initiliaze without any values set.

                                  This is exactly what @Christian-Ehrlicher has ask you to do: always initialize your member variables in constructor this is for all constructors.
                                  So if you add a call to clearMessage() in your default constructor, you will probably solve your issue.

                                  It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                                  1 Reply Last reply
                                  0

                                  • Login

                                  • Login or register to search.
                                  • First post
                                    Last post
                                  0
                                  • Categories
                                  • Recent
                                  • Tags
                                  • Popular
                                  • Users
                                  • Groups
                                  • Search
                                  • Get Qt Extensions
                                  • Unsolved