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. It's possible to call c++ function from qml and update a ListModel?
Qt 6.11 is out! See what's new in the release blog

It's possible to call c++ function from qml and update a ListModel?

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
15 Posts 3 Posters 6.4k 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.
  • V Offline
    V Offline
    vladstelmahovsky
    wrote on last edited by
    #5

    Have thought about your list gets out of scope?
    Cant see full sources, so cant say 100% sure, but it looks like it is

    sdsoldiS 1 Reply Last reply
    1
    • V vladstelmahovsky

      Have thought about your list gets out of scope?
      Cant see full sources, so cant say 100% sure, but it looks like it is

      sdsoldiS Offline
      sdsoldiS Offline
      sdsoldi
      wrote on last edited by sdsoldi
      #6

      I feel the delay in answering...

      I can't paste my code here... I have this error message when I post it: Post content was flagged as spam by Akismet.com

      Edit:

      I suppose that I need "refresh" main.qml or reload it.

      Here is my main.cpp

      #include <QGuiApplication>
      #include <QQmlApplicationEngine>
      #include <QtQml>
      
      #include "Excel.h"
      
      int main(int argc, char *argv[])
      {
          QGuiApplication app(argc, argv);
      
          qmlRegisterType<Excel>("com.myself", 1, 0, "Excel");
      
          QQmlApplicationEngine engine;
          engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
      
          QStringList dataList;
          dataList.append("wololo");
      
          engine.rootContext()->setContextProperty( "cppModel", QVariant::fromValue(dataList) );
      
          return app.exec();
      }
      

      Class of excel file. I'm loading xlsxdocument plugin.
      Excel.h

      #ifndef EXCEL_H
      #define EXCEL_H
      
      #include <QObject>
      #include "xlsx/xlsxdocument.h"
      #include "xlsx/xlsxabstractsheet.h"
      
      class Excel : public QObject
      {
          Q_OBJECT
      public:
          Q_INVOKABLE getExcel(QString path);
      
      signals:
      
      public slots:
      };
      
      #endif // EXCEL_H
      

      Here is my function that I'm trying to update my combobox model.
      Excel.cpp

      #include "Excel.h"
      #include <QDebug>
      #include <QQmlApplicationEngine>
      #include <QtQml>
      
      Excel::getExcel(QString path)
      {
          path.remove(0,8);
          qDebug() << path;
          QXlsx::Document xlsx(path);
          xlsx.selectSheet("MOULD DIMENSIONS");
          //etc..
      
          QQmlApplicationEngine engine;
          QStringList dataList;
          dataList.append("Item 2");
          engine.rootContext()->setContextProperty( "cppModel", QVariant::fromValue(dataList) );
      }
      

      And here is my main qml.
      main.qml

      import QtQuick 2.5
      import QtQuick.Window 2.2
      import QtQuick.Controls 1.4
      import QtQuick.Dialogs 1.2
      import com.myself 1.0
      
      
      Window {
          visible: true
      
          Excel {
              id: excel
          }
      
          Button {
              id: btnOpen
              width: 125
              text: qsTr("Open Excel")
              clip: false
          }
      
          ComboBox {
              id: combo
              model: cppModel
          }
      
          FileDialog {
              id: fileDialog
              title: "Please choose a file"
              folder: shortcuts.home
              onAccepted: {
                  excel.getExcel(fileDialog.fileUrls.toString());
      
              }
          }
          Connections {
              target: btnOpen
              onClicked: fileDialog.visible = true
          }
      }
      

      When I run, the combobox has only 1 item. 'wololo' item.
      And when I open a Excel file, I need to change the combobox items. In this example I need to add 'Item 2' item to combobox.

      But is not working.

      1 Reply Last reply
      0
      • sierdzioS Offline
        sierdzioS Offline
        sierdzio
        Moderators
        wrote on last edited by sierdzio
        #7

        The 'engine' you create in getExcel() is not the same object as the one you create in main.cpp... so you are setting the root property on a different engine than the one you use to display QML :-)

        To fix this, just pass the engine (or the root context) pointer to your Excel class and use it in getExcel().

        (Z(:^

        sdsoldiS 1 Reply Last reply
        1
        • sierdzioS Offline
          sierdzioS Offline
          sierdzio
          Moderators
          wrote on last edited by sierdzio
          #8

          Another option is to use parent-child hierarchy instead of root properties.

          So, in QML:

          Excel {
            ComboBox {
              id: combo
              objectName: "combo"
            }
          }
          

          And then set model from CPP:

          // Pseudocode, written from memory. Please check the docs to be sure:
          QObject *combo = findChildren<QQuickItem*>("combo"); // combo is a child of Excel in QML!
          if (combo) {
            combo->setProperty("model", QVariant::fromValue(dataList) );
          }
          

          Not sure which one you'll find more aesthetic (also not sure if the second option would work at all ;-) ).

          (Z(:^

          1 Reply Last reply
          1
          • sierdzioS sierdzio

            The 'engine' you create in getExcel() is not the same object as the one you create in main.cpp... so you are setting the root property on a different engine than the one you use to display QML :-)

            To fix this, just pass the engine (or the root context) pointer to your Excel class and use it in getExcel().

            sdsoldiS Offline
            sdsoldiS Offline
            sdsoldi
            wrote on last edited by
            #9

            @sierdzio said:

            The 'engine' you create in getExcel() is not the same object as the one you create in main.cpp... so you are setting the root property on a different engine than the one you use to display QML :-)

            To fix this, just pass the engine (or the root context) pointer to your Excel class and use it in getExcel().

            Oh!! It's true... I supose that If I create a engine on main, I can use It on another cpp or h class...

            But now I have a another question... How I can pass engine, or root from main to qml and them from qml to function?

            Anyway, I will try the parent-child

            1 Reply Last reply
            0
            • sierdzioS Offline
              sierdzioS Offline
              sierdzio
              Moderators
              wrote on last edited by
              #10

              @sdsoldi said:

              How I can pass engine, or root from main to qml and them from qml to function?

              You can create a singleton class in C++, pass the engine pointer to it in main.cpp, and then simply access it in your Excel class. This is probably the simplest solution, although singletons do have their drawbacks.

              Or add the engine as a context property to QML, then assign it to Excel object... although that seems awkward.

              (Z(:^

              1 Reply Last reply
              1
              • V Offline
                V Offline
                vladstelmahovsky
                wrote on last edited by
                #11

                or use
                QQmlEngine *qmlEngine(const QObject *object)

                sdsoldiS 1 Reply Last reply
                2
                • V vladstelmahovsky

                  or use
                  QQmlEngine *qmlEngine(const QObject *object)

                  sdsoldiS Offline
                  sdsoldiS Offline
                  sdsoldi
                  wrote on last edited by
                  #12

                  @vladstelmahovsky Can you explain it please?

                  sierdzioS 1 Reply Last reply
                  0
                  • sdsoldiS sdsoldi

                    @vladstelmahovsky Can you explain it please?

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

                    @sdsoldi

                    It is a static method of the engine. SO you can probably use it like this (in Excel class):

                        QQmlEngine *engine = qmlEngine(this); // because "this" is an item you have added to QML
                        QStringList dataList;
                        dataList.append("Item 2");
                        engine.rootContext()->setContextProperty( "cppModel", QVariant::fromValue(dataList) );
                    

                    (Z(:^

                    sdsoldiS 1 Reply Last reply
                    1
                    • sierdzioS sierdzio

                      @sdsoldi

                      It is a static method of the engine. SO you can probably use it like this (in Excel class):

                          QQmlEngine *engine = qmlEngine(this); // because "this" is an item you have added to QML
                          QStringList dataList;
                          dataList.append("Item 2");
                          engine.rootContext()->setContextProperty( "cppModel", QVariant::fromValue(dataList) );
                      
                      sdsoldiS Offline
                      sdsoldiS Offline
                      sdsoldi
                      wrote on last edited by
                      #14

                      @sierdzio @vladstelmahovsky
                      Oh my god! It's as simple as that...

                      Thank you very much!

                      1 Reply Last reply
                      0
                      • V Offline
                        V Offline
                        vladstelmahovsky
                        wrote on last edited by
                        #15

                        yep, but dont forget to check for null

                        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