Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Need advice. Multiple Loader and values from C++
Forum Updated to NodeBB v4.3 + New Features

Need advice. Multiple Loader and values from C++

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
4 Posts 2 Posters 335 Views 1 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.
  • K Offline
    K Offline
    Kuzma30
    wrote on 18 Oct 2022, 14:46 last edited by
    #1

    I have many multichannel sensors (8 channel per sensor ). Number of connected sensors may be different. I need show data from this sensors as chart .
    Now I have such code
    main.qml

    import QtQuick 2.0
    
    Window {
        id: root
        width: 640
        height: 480
        visible: true
    
        Item{
            id: menuShowArea
            property string nonActiveMenuColor: "green"
            property string activeMenuColor: "red"
            property int activeMenuNumber: 1
    
    
            Rectangle {
                id: menu_1
                width: 40
                height: 40
                color: menuShowArea.activeMenuColor
                border.width: 1
                border.color: Qt.lighter(color)
    
                MouseArea {
                    anchors.fill: parent
    
                    onClicked: {
                        activeWindowShow.source = "Background_1.qml"
                        menuShowArea.activeMenuNumber = 1
                        menu_1.color = menuShowArea.activeMenuColor
                        menu_2.color = menuShowArea.nonActiveMenuColor
                    }
                }
            }
            Rectangle {
                id: menu_2
                width: 40
                height: 40
                color: menuShowArea.nonActiveMenuColor
                border.width: 1
                border.color: Qt.lighter(color)
    
                anchors.left: menu_1.left
                anchors.top: menu_1.bottom
    
                MouseArea {
                    anchors.fill: parent
    
                    onClicked: {
                        activeWindowShow.source = "Background_2.qml"
                        menuShowArea.activeMenuNumber = 2
                        menu_1.color = menuShowArea.nonActiveMenuColor
                        menu_2.color = menuShowArea.activeMenuColor
                    }
                }
            }
            property alias hub_1: activeWindowShow.item
    
            property int numberOfHub: 2
            property int showAreaForOneHubHorizontal: ((root.width-menu_1.width)/menuShowArea.numberOfHub)
            property int showAreaForOneHubVertical: root.height
    
            Loader {
                property int hubNumber: 1
    
                id: activeWindowShow
    
                anchors.left: menu_1.right
                anchors.top: menu_1.top
                source: "Background_1.qml"
                width: menuShowArea.showAreaForOneHubHorizontal
                height: menuShowArea.showAreaForOneHubVertical
            }
            property alias hub_2: activeWindowShow2.item
            Loader {
                property int hubNumber: 2
    
                id: activeWindowShow2
    
                anchors.left: activeWindowShow.right
                anchors.top: activeWindowShow.top
                source: "Background_1.qml"
                width: menuShowArea.showAreaForOneHubHorizontal
                height: menuShowArea.showAreaForOneHubVertical
                visible: (menuShowArea.numberOfHub<=2 ? "true" : "false")
            }
            property alias hub_3: activeWindowShow3.item
            Loader {
                property int hubNumber: 3
    
                id: activeWindowShow3
    
                anchors.left: activeWindowShow2.right
                anchors.top: activeWindowShow2.top
                source: "Background_1.qml"
                width: menuShowArea.showAreaForOneHubHorizontal
                height: menuShowArea.showAreaForOneHubVertical
                visible: (menuShowArea.numberOfHub<=3 ? "true" : "false")
            }
            property alias hub_4: activeWindowShow4.item
            Loader {
                property int hubNumber: 4
    
                id: activeWindowShow4
    
                anchors.left: activeWindowShow3.right
                anchors.top: activeWindowShow3.top
                source: "Background_1.qml"
                width: menuShowArea.showAreaForOneHubHorizontal
                height: menuShowArea.showAreaForOneHubVertical
                visible: (menuShowArea.numberOfHub<=4 ? "true" : "false")
            }
    
        }
    }
    

    Background_1.qml

    import QtQuick 2.0
    
    Rectangle {
        id: backgroundOfChart
        color: "green"
        property int barHeightInPercent: 130 //висота стовпчика у % від заданого значення виливу
        property int valueMaxInPercent: 110 //максимальне відхилення заданого значення виливу, у %
        property int valueMinInPercent: 90 //мінімальне відхилення заданого значення виливу, у %
        property double setValue: 100 //заданого значення виливу, у %
    
        property int hubNumber: 1 //порядковий номер хабу
    
        anchors.fill: parent
    
    //    height: 300 // висота стовпчика, має бути barHeightInPercent % від заданого значення виливу
    //    width: 300  // залежить від кількості хабів
    
        Rectangle {
            id: rect_1
            property double realValue //поточне значення виливу
            property bool errorFlag //флаг виходу за встановлені межі
            anchors.left: parent.left
            anchors.bottom: parent.bottom
    
            realValue: 30
            errorFlag: (((backgroundOfChart.setValue/realValue)*100/backgroundOfChart.valueMaxInPercent > 1) || ((backgroundOfChart.setValue/realValue)*100/backgroundOfChart.valueMinInPercent < 1) ? true : false)
            color: (errorFlag ===  true ? "red" : "blue")
            height: realValue*(backgroundOfChart.height*100/backgroundOfChart.barHeightInPercent)/backgroundOfChart.setValue
            width: backgroundOfChart.width/8
            border.width: 1
            border.color: Qt.lighter(color)
            objectName: "rect_1"
        }
        Rectangle {
            id: rect_2
            property double realValue //поточне значення виливу
            property bool errorFlag //флаг виходу за встановлені межі
    
            anchors.left: rect_1.right
            anchors.bottom: parent.bottom
    
            realValue: 50
            errorFlag: (((backgroundOfChart.setValue/realValue)*100/backgroundOfChart.valueMaxInPercent > 1) || ((backgroundOfChart.setValue/realValue)*100/backgroundOfChart.valueMinInPercent < 1) ? true : false)
            color: (errorFlag ===  true ? "red" : "blue")
            height: realValue*(backgroundOfChart.height*100/backgroundOfChart.barHeightInPercent)/backgroundOfChart.setValue
            width: backgroundOfChart.width/8
            border.width: 1
            border.color: Qt.lighter(color)
        }
        Rectangle {
            id: rect_3
            property double realValue //поточне значення виливу
            property bool errorFlag //флаг виходу за встановлені межі
    
            anchors.left: rect_2.right
            anchors.bottom: parent.bottom
    
            realValue: 89
            errorFlag: (((backgroundOfChart.setValue/realValue)*100/backgroundOfChart.valueMaxInPercent > 1) || ((backgroundOfChart.setValue/realValue)*100/backgroundOfChart.valueMinInPercent < 1) ? true : false)
            color: (errorFlag ===  true ? "red" : "blue")
            height: realValue*(backgroundOfChart.height*100/backgroundOfChart.barHeightInPercent)/backgroundOfChart.setValue
            width: backgroundOfChart.width/8
            border.width: 1
            border.color: Qt.lighter(color)
        }
        Rectangle {
            id: rect_4
            property double realValue //поточне значення виливу
            property bool errorFlag //флаг виходу за встановлені межі
    
            anchors.left: rect_3.right
            anchors.bottom: parent.bottom
            realValue: 92
            errorFlag: (((backgroundOfChart.setValue/realValue)*100/backgroundOfChart.valueMaxInPercent > 1) || ((backgroundOfChart.setValue/realValue)*100/backgroundOfChart.valueMinInPercent < 1) ? true : false)
            color: (errorFlag ===  true ? "red" : "blue")
            height: realValue*(backgroundOfChart.height*100/backgroundOfChart.barHeightInPercent)/backgroundOfChart.setValue
            width: backgroundOfChart.width/8
            border.width: 1
            border.color: Qt.lighter(color)
        }
        Rectangle {
            id: rect_5
            property double realValue //поточне значення виливу
            property bool errorFlag //флаг виходу за встановлені межі
    
            anchors.left: rect_4.right
            anchors.bottom: parent.bottom
            realValue: 90
            errorFlag: (((backgroundOfChart.setValue/realValue)*100/backgroundOfChart.valueMaxInPercent > 1) || ((backgroundOfChart.setValue/realValue)*100/backgroundOfChart.valueMinInPercent < 1) ? true : false)
            color: (errorFlag ===  true ? "red" : "blue")
            height: realValue*(backgroundOfChart.height*100/backgroundOfChart.barHeightInPercent)/backgroundOfChart.setValue
            width: backgroundOfChart.width/8
            border.width: 1
            border.color: Qt.lighter(color)
        }
        Rectangle {
            id: rect_6
            property double realValue //поточне значення виливу
            property bool errorFlag //флаг виходу за встановлені межі
    
            anchors.left: rect_5.right
            anchors.bottom: parent.bottom
            realValue: 110
            errorFlag: (((backgroundOfChart.setValue/realValue)*100/backgroundOfChart.valueMaxInPercent > 1) || ((backgroundOfChart.setValue/realValue)*100/backgroundOfChart.valueMinInPercent < 1) ? true : false)
            color: (errorFlag ===  true ? "red" : "blue")
            height: realValue*(backgroundOfChart.height*100/backgroundOfChart.barHeightInPercent)/backgroundOfChart.setValue
            width: backgroundOfChart.width/8
            border.width: 1
            border.color: Qt.lighter(color)
        }
        Rectangle {
            id: rect_7
            property double realValue //поточне значення виливу
            property bool errorFlag //флаг виходу за встановлені межі
    
            anchors.left: rect_6.right
            anchors.bottom: parent.bottom
            realValue: 109
            errorFlag: (((backgroundOfChart.setValue/realValue)*100/backgroundOfChart.valueMaxInPercent > 1) || ((backgroundOfChart.setValue/realValue)*100/backgroundOfChart.valueMinInPercent < 1) ? true : false)
    
            color: (errorFlag ===  true ? "red" : "blue")
            height: realValue*(backgroundOfChart.height*100/backgroundOfChart.barHeightInPercent)/backgroundOfChart.setValue
            width: backgroundOfChart.width/8
            border.width: 1
            border.color: Qt.lighter(color)
        }
        Rectangle {
            id: rect_8
            property double realValue //поточне значення виливу
            property bool errorFlag //флаг виходу за встановлені межі
    
            anchors.left: rect_7.right
            anchors.bottom: parent.bottom
            realValue: 111
            errorFlag: (((backgroundOfChart.setValue/realValue)*100/backgroundOfChart.valueMaxInPercent > 1) || ((backgroundOfChart.setValue/realValue)*100/backgroundOfChart.valueMinInPercent < 1) ? true : false)
    
            color: (errorFlag ===  true ? "red" : "blue")
            height: realValue*(backgroundOfChart.height*100/backgroundOfChart.barHeightInPercent)/backgroundOfChart.setValue
            width: backgroundOfChart.width/8
            border.width: 1
            border.color: Qt.lighter(color)
        }
    
    }
    
    

    main.cpp

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlContext>
    #include <QQuickItem>
    #include <QTimer>
    #include <QtDebug>
    #include <QRandomGenerator>
    #include "hubchannel.h"
    //#include <QLocale>
    //#include <QTranslator>
    
    #include <QQuickView>
    
    
    void checkItem(QQmlApplicationEngine *pEngine);
    
    HubChannel *channel_1;
    
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
        QQmlApplicationEngine engine("qrc:/QML/main.qml");
    
        QTimer::singleShot(2000, [&]() {
            checkItem(&engine);
        });
        QTimer::singleShot(2000, [&]() {
            checkItem(&engine);
        });
        return app.exec();
    }
    
    void checkItem(QQmlApplicationEngine *pEngine) {
        QQuickWindow *window = qobject_cast<QQuickWindow *>(pEngine->rootObjects().first());
        QQuickItem *rect_1 = window->findChild<QQuickItem *>("rect_1");
        if (rect_1)
        {
            int h = channel_1->getChannelData();
            rect_1->setProperty("realValue", QVariant(h));
        }
    }
    

    hubchannel.cpp

    #include "hubchannel.h"
    #include <QRandomGenerator>
    
    HubChannel::HubChannel(QObject *parent)
        : QObject{parent}
    {
        double m_channelData=QRandomGenerator::global()->bounded(90,120);;
        int m_channelNumber=1;
    }
    
    double HubChannel::getChannelData()
    {
        double h = QRandomGenerator::global()->bounded(90,120);
        return h;
    }
    void HubChannel::setChannelData(double channelData)
    {
        m_channelData=channelData;
    }
    
    

    and
    hubchannel.h

    #ifndef HUBCHANNEL_H
    #define HUBCHANNEL_H
    
    #include <QObject>
    
    class HubChannel : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(double channelData READ getChannelData WRITE setChannelData)
    public:
        explicit HubChannel(QObject *parent = nullptr);
        double getChannelData();
        void setChannelData(double channelData);
        int getChannelNumber();
    private:
        double m_channelData;
        int m_channelNumber;
    signals:
    
    };
    
    #endif // HUBCHANNEL_H
    

    It woks with bug. Value of first channel changing only one. If I add to checkItem(QQmlApplicationEngine *pEngine) function random value for second channel it doesn't work.

    void checkItem(QQmlApplicationEngine *pEngine) {
        QQuickWindow *window = qobject_cast<QQuickWindow *>(pEngine->rootObjects().first());
        QQuickItem *rect_1 = window->findChild<QQuickItem *>("rect_1");
        if (rect_1)
        {
            int h = channel_1->getChannelData();
            rect_1->setProperty("realValue", QVariant(h));
        }
    
        QQuickItem *rect_2 = window->findChild<QQuickItem *>("rect_2");
        if (rect_2)
        {
            int h = channel_2->getChannelData();
            rect_2->setProperty("realValue", QVariant(h));
        }
    }
    

    And I don't know how to set values for another Loader

            Loader {
                property int hubNumber: 2
    
                id: activeWindowShow2
    
                anchors.left: activeWindowShow.right
                anchors.top: activeWindowShow.top
                source: "Background_1.qml"
                width: menuShowArea.showAreaForOneHubHorizontal
                height: menuShowArea.showAreaForOneHubVertical
                visible: (menuShowArea.numberOfHub<=2 ? "true" : "false")
            }
    

    I am newby in C++ and QML :)

    1 Reply Last reply
    0
    • fcarneyF Offline
      fcarneyF Offline
      fcarney
      wrote on 20 Oct 2022, 18:07 last edited by
      #2

      @Kuzma30 said in Need advice. Multiple Loader and values from C++:

      void checkItem(QQmlApplicationEngine *pEngine) {
      QQuickWindow *window = qobject_cast<QQuickWindow *>(pEngine->rootObjects().first());
      QQuickItem *rect_1 = window->findChild<QQuickItem *>("rect_1");
      if (rect_1)
      {
      int h = channel_1->getChannelData();
      rect_1->setProperty("realValue", QVariant(h));
      }

      QQuickItem *rect_2 = window->findChild<QQuickItem *>("rect_2");
      if (rect_2)
      {
          int h = channel_2->getChannelData();
          rect_2->setProperty("realValue", QVariant(h));
      }
      

      }

      Dont' do this. Expose C++ objects to QML. Do NOT expose QML objects to C++.

      C++ is a perfectly valid school of magic.

      1 Reply Last reply
      2
      • K Offline
        K Offline
        Kuzma30
        wrote on 23 Oct 2022, 12:02 last edited by Kuzma30
        #3

        I made small refactor of my code (add Repeater where it is possible)
        https://github.com/Kuzma30/QML
        Now I can set values for ch_1-ch_8
        https://github.com/Kuzma30/QML/blob/0454f7a0c06eaf989dcc3f2dcc5e8973b4e0cfe9/main.cpp#L24-L31

        I need during runtime dynamically change this value
        https://github.com/Kuzma30/QML/blob/0454f7a0c06eaf989dcc3f2dcc5e8973b4e0cfe9/hub.qml#L29
        This doesn't work. I see 4 hub_channel
        https://github.com/Kuzma30/QML/blob/0454f7a0c06eaf989dcc3f2dcc5e8973b4e0cfe9/main.cpp#L33

        Another question. I have two model index
        model: [ch_1, ch_2, ch_3, ch_4, ch_5, ch_6, ch_7, ch_8]
        https://github.com/Kuzma30/QML/blob/0454f7a0c06eaf989dcc3f2dcc5e8973b4e0cfe9/hub_wiev.qml#L20
        and model: charts.numberOfHub
        https://github.com/Kuzma30/QML/blob/0454f7a0c06eaf989dcc3f2dcc5e8973b4e0cfe9/hub.qml#L29
        How to set different values for ch_1, ch_2, ch_3, ch_4, ch_5, ch_6, ch_7, ch_8 depending of charts.numberOfHub?

        1 Reply Last reply
        0
        • K Offline
          K Offline
          Kuzma30
          wrote on 29 Oct 2022, 11:28 last edited by
          #4

          I made another code refactor.
          Now it uses QList for stroring values such color, height of bar, status for each of 8 channel of sensor. I use only one sensor with 8 channel now(and emulate it as random() and QTimer)
          What I get at this moment

          1. The height of each bar is changed every second
          2. Color changing not working on QML side. On C++ it change status and color when data is changed.
          3. I get error during program run
          qrc:/QML/qml/mainView/hub_wiev.qml:21:13: QML Rectangle: Binding loop detected for property "realValue"
          

          Actual code for this error is here https://github.com/Kuzma30/QML/commit/c60a1a7a87090eb2e48cc36a0081953b094c93b1

          1 Reply Last reply
          0

          1/4

          18 Oct 2022, 14:46

          • Login

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