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. Unable to test QT/QML model within model functionality to draw charts on UI.
Forum Updated to NodeBB v4.3 + New Features

Unable to test QT/QML model within model functionality to draw charts on UI.

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
1 Posts 1 Posters 93 Views
  • 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.
  • J Offline
    J Offline
    jigarp
    wrote on last edited by
    #1

    Hello i'm trying to create a view where user can set individual count of chart in their respective item. Basically using nested model concept where the top model is just a layout and in inner model i'm creating a chart.
    Here i'm attaching all the code for reference. I'm able to use outer model but inner model is not working.
    Here i've attached full project source code
    I'm using Qt 6.2 in Ubuntu environment.
    Provide your suggestions.

    Main.qml

    import QtQuick
    import QtQuick.Window
    import QtQuick 6.2
    import QtQuick.Controls 6.2
    import QtQuick.Layouts 1.3
    import QtCharts 2.5
    import "."
    
    Window {
        width: 640
        height: 480
        visible: true
        title: qsTr("Hello World")
    
        GridLayout {
            id: viewGridLayout
            anchors.fill: parent
            anchors.margins: 10
            columns: 2
            rows: 4
            columnSpacing: 10
            rowSpacing: 10
            flow: GridLayout.LeftToRight
            Layout.leftMargin: 3
            Layout.rightMargin: 0
            Layout.topMargin: 3
            Layout.bottomMargin: 3
            Repeater {
                id: chartRepeater
                model: monitoringScreen.graphModel
                Component.onCompleted: {
                    console.log("chartRepeater", model)
                }
    
                delegate: ColumnLayout {
                    id: chartRepeaterColumnLayout
                    Layout.fillHeight: true
                    Layout.fillWidth: true
                    Layout.row: 0 + index
                    Layout.column: 0
                    spacing: 1
    
                    Component.onCompleted: {
                        console.log("chartRepeaterColumnLayout", index, model)
                    }
    
                    Repeater {
                        id: seriesRepeater
                        property int rowIndex: index
                        //                    model: chartRepeater.model[index].GraphParam
                        model: monitoringScreen.graphModel.m_Items
                        Component.onCompleted: {
                            console.log("seriesRepeater", index, model)
                        }
    
                        //                    delegate: {
                        //                        console.log("seriesRepeater model:", model);
                        //                        if (model && model.length > 0 && model[0].GraphParam) {
                        //                            console.log("seriesRepeater GraphParam:", model[0].GraphParam);
                        //                            return ChartViewWidget {
                        //                                paramTitle: model[0].GraphParam[0].GraphTitle
                        //                                // Add other properties as needed
                        //                            }
                        //                        } else {
                        //                            console.error("Invalid model data at index:", index);
                        //                            return Item {} // Placeholder item to prevent errors
                        //                        }
                        //                    }
                        delegate: ChartViewWidget {
                            visible: true
                            paramTitle: model.GraphTitle
                            yaxisMinValue: -5
                            yaxisMaxValue: 5
                            Component.onCompleted: {
                                console.log("ChartViewWidget", index)
                            }
                        }
    
                        //                    delegate: Rectangle {
                        //                        color: "red"
                        //                        opacity: 0.6
                        //                        Layout.fillHeight: true
                        //                        Layout.fillWidth: true
                        //                        Component.onCompleted: {
                        //                            console.log("Rectangle", index)
                        //                        }
                        //                    }
                    }
                }
            }
        }
    }
    
    

    ChartViewWidget.qml

    
    /*
    This is a UI file (.ui.qml) that is intended to be edited in Qt Design Studio only.
    It is supposed to be strictly declarative and only uses a subset of QML. If you edit
    this file manually, you might introduce QML code that is not supported by Qt Design Studio.
    Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files.
    */
    import QtQuick 6.2
    import QtQuick.Controls 6.2
    import QtQuick.Layouts 1.3
    import QtQuick.Controls.Universal 2.12
    import QtCharts 2.5
    
    RowLayout {
        id: chartviewRowLayout
        Layout.fillHeight: true
        Layout.fillWidth: true
        spacing: 0
    
        property alias paramTitle: paramTitleText.text
        property alias yaxisMinValue: yAxisLineSeries.min
        property alias yaxisMaxValue: yAxisLineSeries.max
        property alias chartWidget: chartType
    
        Rectangle {
            Layout.fillHeight: true
            Layout.minimumWidth: 50
            color: "#1d2027"
            Text {
                id: paramTitleText
                anchors.fill: parent
                color: "#048E93"
                horizontalAlignment: Text.AlignRight
                verticalAlignment: Text.AlignVCenter
                textFormat: Text.RichText
            }
        }
        Rectangle {
            Layout.fillHeight: true
            Layout.fillWidth: true
            color: "#1d2027"
            ChartView {
                id: chartType
                enabled: true
                smooth: true
                backgroundRoundness: 0
                legend.visible: false
                plotAreaColor: "#1d2027"
                backgroundColor: "#1d2027"
                margins.top: 0
                margins.bottom: 0
                margins.right: 3
                margins.left: 0
                anchors.fill: parent
    
                LineSeries {
                    id: lineSeries
                    axisX: xAxisLineSeries
                    axisY: yAxisLineSeries
                    color: "#048E93"
                }
                ValuesAxis {
                    id: xAxisLineSeries
                    min: 0
                    max: 500
                    gridVisible: false
                    tickCount: 3
                    visible: false
                }
                ValuesAxis {
                    id: yAxisLineSeries
                    min: -1
                    max: 1
                    gridVisible: false
                    tickCount: 3
                    labelsColor: "#999999"
                }
            }
    
            Connections {
                target: chartType
                Component.onCompleted: {
                    console.log("Chart Created")
                }
            }
        }
    }
    
    

    graphmodel.cpp

    #include "graphmodel.h"
    
    GraphModel::GraphModel(QObject* parent)
            : QAbstractListModel(parent) {
    
    }
    const QList<double> GraphModel::m_SampledData =
            {
        0.0449999999999999, 0.0449999999999999,
    };
    int GraphModel::rowCount(const QModelIndex& parent) const {
        qDebug() << "rowCount:" << m_Items.size();
        if (parent.isValid())
            return 0;
        return m_Items.size();
    }
    
    QVariant GraphModel::data(const QModelIndex& index, int role) const {
        qDebug() << "data:" << index.row() << role;
        if (!index.isValid())
            return QVariant();
        if (index.row() < 0 || index.row() >= m_Items.size()) {
            return QVariant();
        }
    
        switch (role) {
        case GraphMaximumCountRole:
            return QVariant(m_Items.at(index.row()).MaximumCount);
        case GraphCursorSizeRole:
            return QVariant(m_Items.at(index.row()).CursorSize);
        case GraphListRole:
            return QVariant::fromValue(m_Items.at(index.row()).GraphParam[0]);
    
            //        return QVariantConstPointer(m_Items.at(index.row()).GraphParam[0]);
            //        return QVariant(m_Items.at(index.row()).GraphParam[0]);
    
        case ParameterId:
            return QVariant(m_Items.at(index.row()).id);
        default:
            return QVariant();
        }
    }
    
    QHash<int, QByteArray> GraphModel::roleNames() const {
        QHash<int, QByteArray> names;
    
        names[GraphTitleRole] = "GraphTitle";
        names[GraphMaximumCountRole] = "GraphMaximumCount";
        names[GraphCursorSizeRole] = "GraphCursorSize";
        names[GraphListRole] = "GraphList";
        names[ParameterId] = "id";
    
        return names;
    }
    
    bool GraphModel::setData(const QModelIndex& index, const QVariant& value, int role) {
        int row = index.row();
        bool isValid = false;
    
        qDebug() << Q_FUNC_INFO;
        if (row >= 0 && row < m_Items.size()) {
            switch (role) {
            case ParameterId:
                if (m_Items[row].id != value.toInt()) {
                    m_Items[row].id = value.toInt();
                    isValid = true;
                }
                break;
    
            case GraphMaximumCountRole:
                if (m_Items[row].MaximumCount != value.toInt()) {
                    m_Items[row].MaximumCount = value.toInt();
                    isValid = true;
                }
                break;
            case GraphCursorSizeRole:
                if (m_Items[row].CursorSize != value.toInt()) {
                    m_Items[row].CursorSize = value.toInt();
                    isValid = true;
                }
                break;
    
            case GraphListRole:
                qDebug() << Q_FUNC_INFO << "GraphListRole" << row << value.toInt();
                if (m_Items[row].GraphParam.size() != value.toInt()) {
                    m_Items[row].GraphParam.clear();
                    for (int i = 0; i < value.toInt(); i++) {
    //                    GraphWidgetParam* localGrWidget = new GraphWidgetParam;
                        GraphWidgetParam localGrWidget;
                        m_Items[row].GraphParam.append(localGrWidget);
                    }
                    isValid = true;
                }
                break;
    
            default:
                break;
            }
    
            if (isValid == true)
                emit dataChanged(index, index, QVector<int>() << role);
        }
    
        return true;
    }
    
    void GraphModel::setGraphTitle(int paramId, const QString& title, int colIndex) {
        int row = getModelParameterIndex(paramId);
    
        if (row >= 0 && row < m_Items.size()) {
            if (colIndex >= 0 && colIndex < m_Items[row].GraphParam.size()) {
                m_Items[row].GraphParam[colIndex].GraphTitle = title;
    //            GraphWidgetParam* pParam = m_Items[row].GraphParam.at(colIndex);
    //            if (pParam->GraphTitle != title) {
    //                pParam->GraphTitle = title;
    
    //                //                qDebug() <<"Graph Title"<< title;
    //            }
            }
        }
    }
    
    void GraphModel::addNewGraphValue(int paramId, int colIndex, double value) {
        int row = getModelParameterIndex(paramId);
    
        if (row >= 0 && row < m_Items.size()) {
            if (colIndex >= 0 && colIndex < m_Items[row].GraphParam.size()) {
                m_Items[row].GraphParam[colIndex].GraphDataValue = value;
    //            GraphWidgetParam* pParam = m_Items[row].GraphParam.at(colIndex);
    //            pParam->GraphDataValue = value;
            }
        }
    }
    
    // void GraphModel::addCharts(int paramId)
    //{
    //     int row = getModelParameterIndex(paramId);
    //     if (row >= 0 && row < m_Items.size())
    //     {
    //         GraphWidgetParam localWidget = {};
    //         m_Items[row].GraphParam.append(localWidget);
    //     }
    // }
    
    void GraphModel::clearCharts(int paramId) {
        int row = getModelParameterIndex(paramId);
        if (row >= 0 && row < m_Items.size()) {
            m_Items[row].GraphParam.clear();
        }
    }
    
    int GraphModel::getModelParameterIndex(int id) {
        qDebug() << "getModelParameterIndex:" << id;
        if (m_Items.size()) {
            for (int i = 0; i < m_Items.size(); i++) {
                if (m_Items.at(i).id == id) {
                    return i;
                }
            }
        }
        return -1;
    }
    
    
    void GraphModel::appendRow(void) {
        int rows = rowCount();
        beginInsertRows(QModelIndex(), rows, rows);
    }
    
    void GraphModel::endAppend(void) {
        endInsertRows();
    }
    
    void GraphModel::AppendModel(GraphModelItem & item) {
        //    StorageModelItem item;
        //    int rows = rowCount();
        appendRow();
        m_Items.append(item);
        endAppend();
    }
    
    void GraphModel::startDataChange(void) {
        beginResetModel();
    }
    
    void GraphModel::updateDataChange(void) {
        endResetModel();
    }
    
    void GraphModel::updateGraphSeriesDataFromIndex(int id, int seriesIndex, QAbstractSeries* series) {
        if (series == nullptr)
            return;
    
        QXYSeries* xySeries = static_cast<QXYSeries*>(series);
    
        if (xySeries == nullptr)
            return;
    
        qreal x(0);
        qreal y(0);
    
        int row = getModelParameterIndex(id);
    
        x = xySeries->count();
        m_TotalCount = m_Items.at(row).MaximumCount;
    
        qDebug() << "Total Count" << m_TotalCount;
    
        //    y = m_SampledData.at(m_SampleIndex);
        //    y = rand()%100;
        //    y = m_Items.at(row).GraphParam.at(seriesIndex).GraphDataValue;
    //    GraphWidgetParam* pParam = m_Items[row].GraphParam.at(seriesIndex);
    
        y = m_Items[row].GraphParam[seriesIndex].GraphDataValue;
    
        if (m_SampleIndex < (m_TotalCount - 4)) {
            m_SampleIndex += 2;
        } else {
            m_SampleIndex = 0;
        }
    
        if (xySeries->count() < m_TotalCount) {
            xySeries->append(x, y);
            qDebug() << "x:y:" << x << y;
            //        qDebug() << "XY Point count:" << xySeries->count();
        } else {
            if ((m_index <= (m_TotalCount - cursorSize))) {
                xySeries->removePoints(m_index, cursorSize);
    
                xySeries->insert(m_index, QPointF(m_index, y));
                xySeries->insert(m_index + 1, QPointF(m_index + 1, 0));
                xySeries->insert(m_index + 2, QPointF(m_index + 2, 0));
                xySeries->insert(m_index + 3, QPointF(m_index + 3, 0));
                xySeries->insert(m_index + 4, QPointF(m_index + 4, 0));
    
                QList<QPointF> points1 = xySeries->points();
    
                points1[m_index + 1].setY(NAN);
                points1[m_index + 2].setY(NAN);
                points1[m_index + 3].setY(NAN);
                points1[m_index + 4].setY(NAN);
    
                xySeries->replace(points1);
            }
    
            if ((m_index < (m_TotalCount - 1))) {
                m_index++;
            } else {
                m_index = 0 + 1;
                qMultiplier++;
    
                if (qMultiplier > 5) {
                    qMultiplier = 1;
                }
            }
        }
    
        double yMin = m_Items[row].GraphParam[seriesIndex].yMin;
        double yMax = m_Items[row].GraphParam[seriesIndex].yMax;
    //    double yMin = pParam->yMin;
    //    double yMax = pParam->yMax;
        if (y > yMax) {
            yMax = y;
            yMax = yMax + (yMax * 0.3);
    
            //        setData(index(row),yaxis_max,GraphModel::GraphYaxisMaxRole);
            //        setYAxisMax(yaxis_max);
        }
        if (y < yMin) {
            yMin = y;
            yMin = yMin + (yMin * 0.3);
            yMin = yMin - yMax;
    
            //        setData(index(row),yaxis_min,GraphModel::GraphYaxisMinRole);
    
            //        setData(id,yaxis_min,GraphModel::GraphYaxisMinRole);
    
            //        setYAxisMin(yaxis_min);
        }
    }
    
    void GraphModel::updateGraphData(int id, QList<int>& grData) {
        int row = -1;
    
        row = getModelParameterIndex(id);
    
        qDebug() << Q_FUNC_INFO << id << row;
    
        if (row != -1) {
            //        m_Items[row].m_GraphData = grData;
    
            emit updateGraphToUi(row);
        }
    }
    
    

    graphmodel.h

    #ifndef GRAPHMODEL_H
    #define GRAPHMODEL_H
    
    #include <QAbstractAxis>
    #include <QAbstractListModel>
    #include <QObject>
    #include <QString>
    #include <QXYSeries>
    #include <QtCharts>
    
    struct GraphWidgetParam {
        QString GraphTitle;
        QList<double> GraphData;
        double GraphDataValue;
        double yMin;
        double yMax;
        int CurrentIndex;
    };
    
    struct GraphModelItem {
        int MaximumCount;
        int CursorSize;
        QList<GraphWidgetParam> GraphParam;
        int id;
    };
    
    class GraphModel : public QAbstractListModel {
        Q_OBJECT
    
    //    Q_PROPERTY(GraphWidgetParam* grWidget READ grWidget NOTIFY grWidgetChanged)
        //    Q_PROPERTY(QList<GraphWidgetParam*> grWidget READ grWidget NOTIFY grWidgetChanged)
    
      public:
        enum GraphModelRole {
    
            GraphTitleRole = Qt::UserRole + 1,
            GraphPointRole,
            GraphMaximumCountRole,
            GraphCursorSizeRole,
            GraphListRole,
    
            ParameterId
        };
        Q_ENUM(GraphModelRole)
    
    //    Q_INVOKABLE GraphWidgetParam* getGraphParam(int index) const {
    ////        if (index < 0 || index >= graphItems.count()) {
    ////            return nullptr;
    ////        }
    ////        GraphModelItem parame;
    
    //        return m_Items.at(index).GraphParam.at(0);
    ////        return parame.GraphParam.at(0); // Assuming you want the first GraphParam in the list
    //    }
    
        explicit GraphModel(QObject* parent = nullptr);
    
        int rowCount(const QModelIndex& parent = QModelIndex()) const override;
    
        QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
    
        QVector<GraphModelItem> m_Items;
    
        QHash<int, QByteArray> roleNames() const override;
    
        bool setData(const QModelIndex& index, const QVariant& value, int role) override;
    
        int getModelParameterIndex(int id);
    
        void updateParameterValuesOnModel(int id, GraphModelItem& item, const QString& valueStr);
    
        void startDataChange(void);
    
        void updateDataChange(void);
    
        void updateGraphData(int id, QList<int>& grData);
    
        //    void addCharts(int paramId);
        void clearCharts(int paramId);
    
        void addNewGraphValue(int paramId, int colIndex, double value);
    
        void setGraphTitle(int paramId, const QString& title, int colIndex);
    
        //    const QList<GraphWidgetParam> * grWidget(int id);
    //    GraphWidgetParam* grWidget();
    
        void appendRow(void);
    
        void endAppend(void);
    
        void AppendModel(GraphModelItem & item);
    
      public slots:
        void updateGraphSeriesDataFromIndex(int id, int seriesIndex, QAbstractSeries* series);
    
      signals:
        void updateGraphToUi(int index);
        void grWidgetChanged();
    
      private:
        static const QList<double> m_SampledData;
        int m_SampleIndex = 0;
        int m_index = 0;
        int m_TotalCount = 0;
        int cursorSize = 5;
    
        qreal qMultiplier = 1;
    
    //    GraphWidgetParam m_GraphWidgetParam;
    
    //    QList<GraphModelItem*> graphItems;
    };
    
    #endif // GRAPHMODEL_H
    
    

    monitoringscreen.cpp

    #include "monitoringscreen.h"
    #include "graphmodel.h"
    
    MonitoringScreen::MonitoringScreen(QObject *parent)
        : QObject{parent}
    {
    
        m_GraphModel = new GraphModel(this);
    
        initMonitoringGraph(1,2);
        initMonitoringGraph(2,1);
        initMonitoringGraph(3,2);
    }
    
    
    MonitoringScreen::~MonitoringScreen() {
        delete m_GraphModel;
    }
    
    
    void MonitoringScreen::initMonitoringGraph(int ParamType, int ChildGraph) {
    
        GraphModelItem item;
    
        item.id = ParamType;
    
        item.MaximumCount = ChildGraph;
        for (int i = 0; i < ChildGraph; i++) {
    //        GraphWidgetParam* localGrWidget = new GraphWidgetParam;
    //        localGrWidget->GraphTitle = QString("%1-%2").arg(ParamType).arg(ChildGraph);
    
    //        localGrWidget->setGraphTitle(QString("%1-%2").arg(ParamType).arg(ChildGraph));
    
            GraphWidgetParam localGrWidget;
            localGrWidget.GraphTitle = QString("%1-%2").arg(ParamType).arg(ChildGraph);
            item.GraphParam.append(localGrWidget);
        }
    
        m_GraphModel->AppendModel(item);
    }
    
    GraphModel *MonitoringScreen::graphModel() const
    {
        return m_GraphModel;
    }
    
    
    

    monitoringscreen.h

    #ifndef MONITORINGSCREEN_H
    #define MONITORINGSCREEN_H
    
    #include <QObject>
    #include "graphmodel.h"
    
    class MonitoringScreen : public QObject
    {
        Q_OBJECT
    
        Q_PROPERTY(GraphModel* graphModel READ graphModel NOTIFY graphModelChanged)
    
    public:
        explicit MonitoringScreen(QObject *parent = nullptr);
        ~MonitoringScreen();
    
        GraphModel *graphModel() const;
    
    signals:
    
        void graphModelChanged();
    
    private:
        void initMonitoringGraph(int ParamType, int ChildGraph);
    
        GraphModel *m_GraphModel = nullptr;
    };
    
    #endif // MONITORINGSCREEN_H
    
    

    main.cpp

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlContext>
    
    #include "monitoringscreen.h"
    
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
    
    
        MonitoringScreen monitoringScreen;
    
        QQmlApplicationEngine engine;
        const QUrl url(u"qrc:/test_graph/Main.qml"_qs);
    
        qRegisterMetaType<GraphWidgetParam>("GraphWidgetParam");
    //    qmlRegisterType<GraphModel>("model.trial", 1, 0, "GraphModel1");
    
        engine.rootContext()->setContextProperty(
            "monitoringScreen", &monitoringScreen);
    
        engine.load(url);
    
        return app.exec();
    }
    
    
    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