Need advice. Multiple Loader and values from C++
-
wrote on 18 Oct 2022, 14:46 last edited by
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.qmlimport 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 :)
-
wrote on 20 Oct 2022, 18:07 last edited by
@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++.
-
wrote on 23 Oct 2022, 12:02 last edited by Kuzma30
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-L31I 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#L33Another 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? -
wrote on 29 Oct 2022, 11:28 last edited by
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- The height of each bar is changed every second
- Color changing not working on QML side. On C++ it change status and color when data is changed.
- 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/4