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. findChild() does not find objectName() of LineSeries from c++ side
QtWS25 Last Chance

findChild() does not find objectName() of LineSeries from c++ side

Scheduled Pinned Locked Moved Solved QML and Qt Quick
7 Posts 3 Posters 281 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.
  • R Offline
    R Offline
    robven
    wrote on last edited by
    #1

    Hi,
    I created this qml component:

    MyChartView.qml
    
    import QtQuick 2.12
    import QtCharts 2.13
    
    
    Item{
        id: root
        objectName:"root"
        width: 600
        height: 440
    
        ChartView{
            id:chartView
            objectName: "chartView"
            anchors.fill: parent
    
            ValuesAxis{
                id:xAxis
                min: 0
                max: 10
            }
    
            ValuesAxis{
                id:yAxis
                min: 0
                max: 10
            }
    
            LineSeries{
                id:lineSeries
                objectName: "lineSeries"
                name: "Linea 1"
                axisX: xAxis
                axisY: yAxis
            }
        }
    }
    
    

    in main.cpp I want to access lineSeries through lineSeriesQobject pointer, but it doesn't find objectName() of lineSeries. Below the code of main.cpp.

    main.cpp
    
    #include <QApplication>
    #include <QObject>
    #include <QQuickView>
    #include <QQmlProperty>
    #include <QQuickItem>
    
        int main(int argc, char *argv[])
    {
    #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    #endif
        QApplication app(argc, argv);
    
        QQuickView view;
        view.setSource(QUrl::fromLocalFile(":/MyChartView.qml"));
    
        QQuickItem *rootObject=view.rootObject();
        if(rootObject){
            qDebug()<<rootObject->objectName();
            QObject *chartViewObject=rootObject->findChild<QObject*>("chartView");
            if(chartViewObject){
                qDebug()<<chartViewObject->objectName();
                QObject* lineSeriesObject=chartViewObject->findChild<QObject*>("lineSeries");
                if(lineSeriesObject){
                    qDebug()<<lineSeriesObject->objectName();
                }
            }
        }
        view.show();
    
        return app.exec();
    }
    
    

    lineSeriesObject pointer return nullptr, what am I doing wrong?

    sierdzioS 1 Reply Last reply
    0
    • R robven

      Hi,
      I created this qml component:

      MyChartView.qml
      
      import QtQuick 2.12
      import QtCharts 2.13
      
      
      Item{
          id: root
          objectName:"root"
          width: 600
          height: 440
      
          ChartView{
              id:chartView
              objectName: "chartView"
              anchors.fill: parent
      
              ValuesAxis{
                  id:xAxis
                  min: 0
                  max: 10
              }
      
              ValuesAxis{
                  id:yAxis
                  min: 0
                  max: 10
              }
      
              LineSeries{
                  id:lineSeries
                  objectName: "lineSeries"
                  name: "Linea 1"
                  axisX: xAxis
                  axisY: yAxis
              }
          }
      }
      
      

      in main.cpp I want to access lineSeries through lineSeriesQobject pointer, but it doesn't find objectName() of lineSeries. Below the code of main.cpp.

      main.cpp
      
      #include <QApplication>
      #include <QObject>
      #include <QQuickView>
      #include <QQmlProperty>
      #include <QQuickItem>
      
          int main(int argc, char *argv[])
      {
      #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
          QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
      #endif
          QApplication app(argc, argv);
      
          QQuickView view;
          view.setSource(QUrl::fromLocalFile(":/MyChartView.qml"));
      
          QQuickItem *rootObject=view.rootObject();
          if(rootObject){
              qDebug()<<rootObject->objectName();
              QObject *chartViewObject=rootObject->findChild<QObject*>("chartView");
              if(chartViewObject){
                  qDebug()<<chartViewObject->objectName();
                  QObject* lineSeriesObject=chartViewObject->findChild<QObject*>("lineSeries");
                  if(lineSeriesObject){
                      qDebug()<<lineSeriesObject->objectName();
                  }
              }
          }
          view.show();
      
          return app.exec();
      }
      
      

      lineSeriesObject pointer return nullptr, what am I doing wrong?

      sierdzioS Offline
      sierdzioS Offline
      sierdzio
      Moderators
      wrote on last edited by
      #2

      @robven findChild() searched recursively so you can just search for lineSeries from rootObject, no need for nested if statements.

      (Z(:^

      1 Reply Last reply
      0
      • R Offline
        R Offline
        robven
        wrote on last edited by robven
        #3

        @sierdzio Thanks for the quick reply.
        Below I update the code as you suggested, but the problem remained the same findChild() still can't find objectName() of lineSeries.

        main.cpp
        
        #include <QApplication>
        #include <QObject>
        #include <QQuickView>
        #include <QQmlProperty>
        #include <QQuickItem>
        
            int main(int argc, char *argv[])
        {
        #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
            QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
        #endif
            QApplication app(argc, argv);
        
            QQuickView view;
            view.setSource(QUrl::fromLocalFile(":/MyChartView.qml"));
        
            QQuickItem *rootObject=view.rootObject();
            if(rootObject){
                qDebug()<<rootObject->objectName();
                QObject *lineSeriesObject=rootObject->findChild<QObject*>("lineSeries",Qt::FindChildOption::FindChildrenRecursively);
                if(lineSeriesObject){
                    qDebug()<<lineSeriesObject->objectName();
                }
            }
            view.show();
        
            return app.exec();
        }
        
        
        1 Reply Last reply
        0
        • R Offline
          R Offline
          robven
          wrote on last edited by
          #4

          Hello, I found the solution to be able to manipulate the LineSeries from the C++ side in QML. I needed this approach because I want to populate the LineSeries from C++ rather than from QML. I have to work with a large number of points, and populating the LineSeries from QML was proving to be too slow. The chart will display 100 randomly generated points as well. Below you will find the main.cpp, main.qml, and MyChartView.qml files.

          main.cpp
          
          #include <QApplication>
          #include <QQmlApplicationEngine>
          #include <QQmlComponent>
          #include<QQmlEngine>
          #include <QAbstractSeries>
          #include <QLineSeries>
          #include <QRandomGenerator>
          
          
          int main(int argc, char *argv[])
          {
          #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
              QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
          #endif
              QApplication app(argc, argv);
          
              QQmlApplicationEngine engine;
          
              const QUrl url(QStringLiteral("qrc:/main.qml"));
          
              QQmlComponent component(&engine, url);
              QObject *rootObject = component.create();
              if (rootObject) {
                  QObject *chartViewObject = rootObject->findChild<QObject *>("chartView");
                  if (chartViewObject) {
                      QAbstractSeries *series = nullptr;
                      QMetaObject::invokeMethod(chartViewObject,
                                                "series",
                                                Q_RETURN_ARG(QAbstractSeries *, series),
                                                Q_ARG(int, 0));
                      if (series) {
                          QLineSeries *qSeries = qobject_cast<QLineSeries *>(series);
                          QList<QPointF> pointFList;
                          QPointF pointF;
                          series->setProperty("name", "Line 1");
                          series->setProperty("color", "#FF8000");
                          for (int i = 0; i < 100; i++) {
                              pointF.setX(i);
                              qint32 randomNumber = QRandomGenerator::global()->bounded(101);
                              pointF.setY(randomNumber);
                              pointFList.push_back(pointF);
                          }
                          qSeries->replace(pointFList);
                      }
                  }
              }
          
          
              return app.exec();
          }
          
          
          main.qml
          
          import QtQuick 2.12
          import QtQuick.Window 2.12
          
          Window {
              id: window
              width: 640
              height: 480
              visible: true
              title: qsTr("Chart")
          
          
              MyChartView{
                  id:myChartView
                  anchors.centerIn: parent
              }
          }
          
          
          MyChartView.qml
          
          import QtQuick 2.12
          import QtCharts 2.13
          
          Item {
              id:root
              objectName: "root"
              width: 600
              height: 440
          
              ChartView{
                  id:chartView
                  objectName: "chartView"
                  anchors.fill: parent
          
                  ValuesAxis{
                      id:xAxis
                      min: 0
                      max: 100
                  }
          
                  ValuesAxis{
                      id:yAxis
                      min: 0
                      max: 100
                  }
          
                  LineSeries{
                      id:lineSeries
                      objectName: "lineSeries"
                      axisX: xAxis
                      axisY:yAxis
                  }
              }
          }
          
          
          GrecKoG 1 Reply Last reply
          0
          • R robven has marked this topic as solved on
          • R robven

            Hello, I found the solution to be able to manipulate the LineSeries from the C++ side in QML. I needed this approach because I want to populate the LineSeries from C++ rather than from QML. I have to work with a large number of points, and populating the LineSeries from QML was proving to be too slow. The chart will display 100 randomly generated points as well. Below you will find the main.cpp, main.qml, and MyChartView.qml files.

            main.cpp
            
            #include <QApplication>
            #include <QQmlApplicationEngine>
            #include <QQmlComponent>
            #include<QQmlEngine>
            #include <QAbstractSeries>
            #include <QLineSeries>
            #include <QRandomGenerator>
            
            
            int main(int argc, char *argv[])
            {
            #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
                QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
            #endif
                QApplication app(argc, argv);
            
                QQmlApplicationEngine engine;
            
                const QUrl url(QStringLiteral("qrc:/main.qml"));
            
                QQmlComponent component(&engine, url);
                QObject *rootObject = component.create();
                if (rootObject) {
                    QObject *chartViewObject = rootObject->findChild<QObject *>("chartView");
                    if (chartViewObject) {
                        QAbstractSeries *series = nullptr;
                        QMetaObject::invokeMethod(chartViewObject,
                                                  "series",
                                                  Q_RETURN_ARG(QAbstractSeries *, series),
                                                  Q_ARG(int, 0));
                        if (series) {
                            QLineSeries *qSeries = qobject_cast<QLineSeries *>(series);
                            QList<QPointF> pointFList;
                            QPointF pointF;
                            series->setProperty("name", "Line 1");
                            series->setProperty("color", "#FF8000");
                            for (int i = 0; i < 100; i++) {
                                pointF.setX(i);
                                qint32 randomNumber = QRandomGenerator::global()->bounded(101);
                                pointF.setY(randomNumber);
                                pointFList.push_back(pointF);
                            }
                            qSeries->replace(pointFList);
                        }
                    }
                }
            
            
                return app.exec();
            }
            
            
            main.qml
            
            import QtQuick 2.12
            import QtQuick.Window 2.12
            
            Window {
                id: window
                width: 640
                height: 480
                visible: true
                title: qsTr("Chart")
            
            
                MyChartView{
                    id:myChartView
                    anchors.centerIn: parent
                }
            }
            
            
            MyChartView.qml
            
            import QtQuick 2.12
            import QtCharts 2.13
            
            Item {
                id:root
                objectName: "root"
                width: 600
                height: 440
            
                ChartView{
                    id:chartView
                    objectName: "chartView"
                    anchors.fill: parent
            
                    ValuesAxis{
                        id:xAxis
                        min: 0
                        max: 100
                    }
            
                    ValuesAxis{
                        id:yAxis
                        min: 0
                        max: 100
                    }
            
                    LineSeries{
                        id:lineSeries
                        objectName: "lineSeries"
                        axisX: xAxis
                        axisY:yAxis
                    }
                }
            }
            
            
            GrecKoG Offline
            GrecKoG Offline
            GrecKo
            Qt Champions 2018
            wrote on last edited by
            #5

            @robven A better solution would be to use VXYModelMapper so the C++ code can stay unaware of the QML code.

            R 1 Reply Last reply
            1
            • GrecKoG GrecKo

              @robven A better solution would be to use VXYModelMapper so the C++ code can stay unaware of the QML code.

              R Offline
              R Offline
              robven
              wrote on last edited by
              #6

              @GrecKo Thanks, I'll try to look into your advice.

              1 Reply Last reply
              0
              • R Offline
                R Offline
                robven
                wrote on last edited by
                #7

                I rewrote the code using VXYModelMapper. It actually results in a more elegant solution and as the Qt documentation points out we keep the C++ side separate from the QML side.

                main.cpp

                #include <QApplication>
                #include <QQmlApplicationEngine>
                #include <QStandardItemModel>
                #include <QStandardItem>
                #include <QRandomGenerator>
                #include <QQmlContext>
                
                
                int main(int argc, char *argv[])
                {
                #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
                    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
                #endif
                    QApplication app(argc, argv);
                
                    //we create a QStandardItemModel object composed of 100 rows and 3 columns
                    QStandardItemModel lineModel(100, 3);
                
                    for (int row = 0; row < lineModel.rowCount(); row++) {
                        QStandardItem *item1 = new QStandardItem(QString::number(row));
                        QStandardItem *item2 = new QStandardItem(QString::number(row));
                        qint32 randomNumber = QRandomGenerator::global()->bounded(101);
                        QStandardItem *item3 = new QStandardItem(QString::number(randomNumber));
                
                        //now I assign the items to lineModel
                        lineModel.setItem(row,0,item1);
                        lineModel.setItem(row,1,item2);
                        lineModel.setItem(row,2,item3);
                    }
                
                    QQmlApplicationEngine engine;
                    engine.rootContext()->setContextProperty("lineModel",&lineModel);
                    const QUrl url(QStringLiteral("qrc:/main.qml"));
                    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                        &app, [url](QObject *obj, const QUrl &objUrl) {
                            if (!obj && url == objUrl)
                                QCoreApplication::exit(-1);
                        }, Qt::QueuedConnection);
                    engine.load(url);
                
                    return app.exec();
                }
                
                

                main.qml

                import QtQuick 2.12
                import QtQuick.Window 2.12
                import QtCharts 2.3
                
                Window {
                    width: 640
                    height: 480
                    visible: true
                    title: qsTr("Hello World")
                
                    ChartView {
                        anchors.fill: parent
                        id: chart
                        antialiasing: true
                
                        ValuesAxis{
                            id: axisX
                            min: 0
                            max: 100
                        }
                
                        ValuesAxis{
                            id: axisY
                            min: 0
                            max: 100
                        }
                
                        LineSeries{
                            id: line
                            name: "Line 1"
                            axisX: axisX
                            axisY: axisY
                        }
                
                        VXYModelMapper {
                            id: modelMapper
                            model: lineModel
                            series: line
                            firstRow: 0
                            xColumn: 1
                            yColumn: 2
                        }
                    }
                
                }
                
                
                1 Reply Last reply
                1

                • Login

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