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. Acess engine within function
Qt 6.11 is out! See what's new in the release blog

Acess engine within function

Scheduled Pinned Locked Moved Solved QML and Qt Quick
17 Posts 2 Posters 8.1k 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.
  • S Offline
    S Offline
    Scottish_Jason
    wrote on last edited by
    #3

    Hi SGaist

    I am simply returning 2 string values from a sqlite database. It works fine if I put all the code in main() but the problem is I want to be able to execute this every time I click the button so I created a function (which can't attach to qml)

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #4

      Do you want to return them as a result of the function call ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • S Offline
        S Offline
        Scottish_Jason
        wrote on last edited by
        #5

        Well I want to return/update the values every time the button is pressed based upon the current qml co-ordinates at that time. I can get the function to launch and grab the appropriate data when I push the button. I just can't update the screen at that point with the new data because engine.rootcontext() doesn't appear to be global. Basically, how can I push stuff to the screen within a function, or is there another more appropriate way to do it?

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #6

          One thing I didn't notice at first. You are creating a new engine, a new ui and a new temporary MyClass object in your clickedButton slots. Looks that's not really what you wanted to do.

          A cleaner way would be to add two properties to your MyClass object and update them with the content of your database.

          class MyClass : public QObject {
          Q_OBJECT
          Q_PROPERTY(QString decile READ decile WRITE setDecile NOTIFY decileChanged)
          Q_PROPERTY(QString postCode READ postCode WRITE setPostCode NOTIFY postCodeChanged)
          
          QString postCode() const { return _postCode; }
          
          signals:
          void decileChanged(const QString& decile);
          void postCodeChanged(const QString& postCode);
          
          public slots:
          void setDecile(const QString& decile) 
          {
              if (_decile == decile) {
                  return;
              }
              _decile = decile;
              emit decileChanged(decile);
          }
          // same for post code
          
          void update(/*Parameters you need*/) {
          // grab data from your database
          setDecile(decileFromDatabase);
          setPostCode(postCodeFromDatabase);
          }
          
          private:
              QString _decile;
              QString _postCode;
          };
          

          Then you only have to use the object in your QML and call update where needed.

          WARNING: Not built nor tested. There might be better designs but the specs were a little short.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • S Offline
            S Offline
            Scottish_Jason
            wrote on last edited by Scottish_Jason
            #7

            Thanks very much for your reply. I am currently trying to implement it now.
            The problem is how do I read the qml latitude and longitude inside the update function. The current GPS co-ordinates are required in order to complete the database check.

            void update(/*Parameters you need*/) {
            
            *** Need GPS co-ordinates to grab data ***
             
            //QVariant latitude = QQmlProperty::read(object2, "icoordlat");
            //QVariant longitude = QQmlProperty::read(object2, "icoordlon");       **<<<< how to read qml variables here?**
            
            // grab data from your database
            
            setDecile(decileFromDatabase);
            setPostCode(postCodeFromDatabase);
            }
            

            Thanks for all your help

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #8

              What are you using to get the GPS data ?

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              S 1 Reply Last reply
              0
              • SGaistS SGaist

                What are you using to get the GPS data ?

                S Offline
                S Offline
                Scottish_Jason
                wrote on last edited by Scottish_Jason
                #9

                @SGaist

                I used QQmlProperty to read *object

                  MyClass myClass;
                  QQmlApplicationEngine engine;
                  QQmlEngine engine2;
                
                   QQmlComponent component(&engine2,QUrl(QStringLiteral("qrc:/MainForm.ui.qml")));
                   QObject *object = component.create();
                
                //
                
                QVariant latitude = QQmlProperty::read(object, "icoordlat");
                QVariant longitude = QQmlProperty::read(object, "icoordlon"); 
                
                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #10

                  It looks like you are trying to go back and forth between QML and C++ rather than trying to use the usual channels to communicate between both.

                  Where are you setting these two values ?

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • S Offline
                    S Offline
                    Scottish_Jason
                    wrote on last edited by Scottish_Jason
                    #11

                    Hey I set them in my MainForm.ui.qml. From my research of QML it seemed this was the common way to communicate between C++ and QML. Basically, I am trying to get these qt positioning values over to C++ so that they can be evaluated against a database and then the output presented on the screen. I didn't think it would be this difficult to interface between the two. Any help sending me down the right path would be great.

                    Mainform.ui.qml

                    import QtQuick 2.5
                    import QtPositioning 5.5
                    import QtLocation 5.5
                    import QtQuick.Controls 1.4
                    
                    
                    Rectangle
                    {
                        width: 360
                        height: 360
                        property alias item1: item1
                        property alias toolButton1: toolButton1
                        property alias src: src
                    property string icoordlat: src.position.coordinate.latitude
                    property string icoordlon: src.position.coordinate.longitude
                        Item
                    {
                        id: item1
                            PositionSource
                            {
                            id: src
                            updateInterval: 1000
                            active: true
                            property double icoordlat: src.position.coordinate.latitude
                            property double icoordlon: src.position.coordinate.longitude
                            }
                    
                    
                    }
                        MouseArea
                        {
                            id: mouseArea
                            anchors.rightMargin: 0
                            anchors.bottomMargin: 0
                            anchors.leftMargin: 0
                            anchors.topMargin: 0
                            anchors.fill: parent
                    
                         Text
                        {
                            id: t1
                            width: 343
                            height: 145
                            font.pointSize: 60
                            anchors.centerIn: parent
                            text: decile
                            anchors.verticalCenterOffset: 9
                            anchors.horizontalCenterOffset: 1
                    
                        }
                        Text
                        {
                            id: t2
                            width: 343
                            height: 106
                            font.pointSize: 44
                            anchors.centerIn: parent
                            text: postcode
                            anchors.verticalCenterOffset: -119
                            anchors.horizontalCenterOffset: 1
                    
                        }
                        Text
                        {
                            id: t3
                            width: 343
                            height: 106
                            font.pointSize: 16
                            anchors.centerIn: parent
                            text: src.position.coordinate.latitude
                            anchors.verticalCenterOffset: 120
                            anchors.horizontalCenterOffset: 1
                    
                        }
                        Text
                        {
                            id: t4
                            width: 343
                            height: 106
                            font.pointSize: 16
                            anchors.centerIn: parent
                            text: src.position.coordinate.longitude
                            anchors.verticalCenterOffset: 160
                            anchors.horizontalCenterOffset: 1
                    
                        }
                    
                        ToolButton
                        {
                            id: toolButton1
                            width: 233
                            height: 233
                            anchors.verticalCenterOffset: 200
                            text: "Refresh"
                    
                    
                        }
                    
                    
                        }
                    }
                    

                    This is where I get the function to execute on button push

                    main.qml

                    Window
                    {
                        visible: true
                    
                        MainForm
                        {
                            toolButton1.onClicked:
                            {
                            obj.clickedButton();
                            }
                            anchors.fill: parent
                    
                        }
                    
                    }
                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #12

                      In your onClick handler, you can retrieve the values from icoordlat, icoordlon since they are properties of your Mainform and pass them to clickButton.
                      Some thing like

                      onClicked: 
                      {
                          obj.clicked(icoordlat, icoordlon);
                      }
                      

                      No need to try to go through the engine.

                      I'd recommend taking a look at the QtQml C++ integration chapter from Qt's documentation.

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      S 1 Reply Last reply
                      0
                      • SGaistS SGaist

                        In your onClick handler, you can retrieve the values from icoordlat, icoordlon since they are properties of your Mainform and pass them to clickButton.
                        Some thing like

                        onClicked: 
                        {
                            obj.clicked(icoordlat, icoordlon);
                        }
                        

                        No need to try to go through the engine.

                        I'd recommend taking a look at the QtQml C++ integration chapter from Qt's documentation.

                        S Offline
                        S Offline
                        Scottish_Jason
                        wrote on last edited by Scottish_Jason
                        #13

                        @SGaist

                        Hi thanks very much for the reply again. I have modified my code and I am able to get the application to compile.
                        I'm able to pass the long & lat over to C++ and get the result (seen with qDebug) but the qml screen data does not get refreshed with :

                        setDecile(decile);
                        setPostCode(postCode);

                        main.h

                        #ifndef MAIN_H
                        #define MAIN_H
                        #include <QObject>
                        #include <QDebug>
                        #include <QQuickItem>
                        #include <QGuiApplication>
                        #include <QQmlApplicationEngine>
                        #include <QDebug>
                        #include <QUrl>
                        #include <QQmlContext>
                        #include <QQmlComponent>
                        #include <QQmlProperty>
                        #include <QSqlDatabase>
                        #include <QtSql>
                        #include <QtPositioning/QGeoCoordinate>
                        #include <QtNetwork/QNetworkAccessManager>
                        #include <QtNetwork/QNetworkReply>
                        #include <QGeoAddress>
                        #include <QObject>
                        #include <QQuickItem>
                        #include <QQuickView>
                        
                        class MyClass : public QObject {
                        Q_OBJECT
                        Q_PROPERTY(QString decile READ decile WRITE setDecile NOTIFY decileChanged)
                        Q_PROPERTY(QString postCode READ postCode WRITE setPostCode NOTIFY postCodeChanged)
                        
                        QString postCode() const { return _postCode; }
                        QString decile() const { return _decile; }
                        
                        signals:
                        void decileChanged(const QString& decile);
                        void postCodeChanged(const QString& postCode);
                        
                        public slots:
                        void setDecile(const QString& decile)
                        {
                            if (_decile == decile) {
                                return;
                            }
                            _decile = decile;
                            emit decileChanged(decile);
                        }
                        void setPostCode(const QString& postCode)
                        {
                            if (_postCode == postCode) {
                                return;
                            }
                            _postCode = postCode;
                            emit postCodeChanged(postCode);
                        }
                        
                        void update(QString icoordlat, QString icoordlon)
                        {
                        
                            QString dbname = "affluence.sqlite";
                            QString filePath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation);
                            filePath.append( "/"+dbname);
                            QSqlDatabase dbsqlite = QSqlDatabase::addDatabase("QSQLITE","dbsqlite");
                        
                            dbsqlite.setDatabaseName(filePath);
                            dbsqlite.open();
                        
                            if (dbsqlite.open())
                            {
                        
                                QString Qlatitude2 = icoordlat.left(6);
                                QString Qlongitude2 = icoordlon.left(6);
                                QString perc = "%";
                                Qlatitude2 = Qlatitude2 + perc;
                                Qlongitude2 = Qlongitude2 + perc;
                                qDebug() << "soup: " << Qlatitude2 << Qlongitude2;
                                QSqlQuery querydb(dbsqlite);
                                querydb.prepare("select * FROM affluence WHERE latitude LIKE :Qlatitude AND longitude LIKE :Qlongitude");
                                querydb.bindValue(":Qlatitude",  Qlatitude2);
                                querydb.bindValue(":Qlongitude",  Qlongitude2);
                                querydb.exec();
                        
                                while (querydb.next())
                                {
                                QString Qlatitude3 = querydb.value(4).toString();
                                QString Qlongitude3 = querydb.value(5).toString();
                                QString decile = querydb.value(3).toString();
                                QString postCode = querydb.value(2).toString();
                        
                                setDecile(decile);
                                setPostCode(postCode);
                                
                                qDebug() << "latitude: " << Qlatitude3 << " longitude: " << Qlongitude3 << " decile: " << decile << "post code:" << postCode;
                                }
                            }
                            else
                            {
                                qDebug() << "can't connect to sqlite " << dbsqlite.lastError();
                            }
                        
                        }
                        
                        private:
                            QString _decile;
                            QString _postCode;
                        };
                        
                        
                        #endif // MAIN_H
                        

                        main.cpp

                        int main(int argc, char *argv[])
                        {
                        
                        
                            QGuiApplication app(argc, argv);
                            MyClass myClass;
                            QQmlApplicationEngine engine;
                            QQmlEngine engine2;
                        
                            QQmlComponent component(&engine2,QUrl(QStringLiteral("qrc:/MainForm.ui.qml")));
                            QObject *object = component.create();
                        
                        
                            engine.rootContext()->setContextProperty(QStringLiteral("obj"), &myClass);
                        
                         
                            engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                        
                            return app.exec();
                        }
                        

                        main.qml

                        import QtQuick 2.5
                        import QtQuick.Window 2.2
                        import QtPositioning 5.5
                        import QtLocation 5.6
                        import QtPositioning 5.2
                        
                        Item
                        {
                        
                        Window
                        {
                            visible: true
                        
                            MainForm
                            {
                                toolButton1.onClicked:
                                {
                                obj.update(icoordlat, icoordlon);
                                }
                                anchors.fill: parent
                        
                            }
                        
                        
                        
                        }
                        }
                        

                        MainForm.ui.qml

                        import QtQuick 2.5
                        import QtPositioning 5.5
                        import QtLocation 5.5
                        import QtQuick.Controls 1.4
                        
                        
                        Rectangle
                        {
                            width: 360
                            height: 360
                            property alias item1: item1
                            property alias toolButton1: toolButton1
                            property alias src: src
                        property string icoordlat: src.position.coordinate.latitude
                        property string icoordlon: src.position.coordinate.longitude
                            Item
                        {
                            id: item1
                                PositionSource
                                {
                                id: src
                                updateInterval: 1000
                                active: true
                                property double icoordlat: src.position.coordinate.latitude
                                property double icoordlon: src.position.coordinate.longitude
                                }
                        
                        
                        }
                            MouseArea
                            {
                                id: mouseArea
                                anchors.rightMargin: 0
                                anchors.bottomMargin: 0
                                anchors.leftMargin: 0
                                anchors.topMargin: 0
                                anchors.fill: parent
                        
                             Text
                            {
                                id: t1
                                width: 343
                                height: 145
                                font.pointSize: 60
                                anchors.centerIn: parent
                                text: decile
                                anchors.verticalCenterOffset: 9
                                anchors.horizontalCenterOffset: 1
                        
                            }
                            Text
                            {
                                id: t2
                                width: 343
                                height: 106
                                font.pointSize: 44
                                anchors.centerIn: parent
                                text: postcode
                                anchors.verticalCenterOffset: -119
                                anchors.horizontalCenterOffset: 1
                        
                            }
                            Text
                            {
                                id: t3
                                width: 343
                                height: 106
                                font.pointSize: 16
                                anchors.centerIn: parent
                                text: src.position.coordinate.latitude
                                anchors.verticalCenterOffset: 120
                                anchors.horizontalCenterOffset: 1
                        
                            }
                            Text
                            {
                                id: t4
                                width: 343
                                height: 106
                                font.pointSize: 16
                                anchors.centerIn: parent
                                text: src.position.coordinate.longitude
                                anchors.verticalCenterOffset: 160
                                anchors.horizontalCenterOffset: 1
                        
                            }
                        
                            ToolButton
                            {
                                id: toolButton1
                                width: 233
                                height: 233
                                anchors.verticalCenterOffset: 200
                                text: "Refresh"
                        
                        
                            }
                        
                        
                            }
                        }
                        
                        1 Reply Last reply
                        0
                        • SGaistS Offline
                          SGaistS Offline
                          SGaist
                          Lifetime Qt Champion
                          wrote on last edited by
                          #14

                          I may have missed it but I don't see any use of obj properties in your code.

                          Interested in AI ? www.idiap.ch
                          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                          S 1 Reply Last reply
                          0
                          • SGaistS SGaist

                            I may have missed it but I don't see any use of obj properties in your code.

                            S Offline
                            S Offline
                            Scottish_Jason
                            wrote on last edited by Scottish_Jason
                            #15

                            @SGaist

                            when I used the "go to slot" option on the button it created the function inside main.qml so I just went with that

                            main.qml

                            import QtQuick 2.5
                            import QtQuick.Window 2.2
                            import QtPositioning 5.5
                            import QtLocation 5.6
                            import QtPositioning 5.2
                            
                            Item
                            {
                            
                            Window
                            {
                                visible: true
                            
                                MainForm
                                {
                                    toolButton1.onClicked:
                                    {
                                    obj.update(icoordlat, icoordlon);
                                    }
                                    anchors.fill: parent
                            
                                }
                            
                            
                            
                            }
                            }
                            

                            and obj is set inside main.cpp

                            int main(int argc, char *argv[])
                            {
                            
                            
                                QGuiApplication app(argc, argv);
                                MyClass myClass;
                                QQmlApplicationEngine engine;
                                QQmlEngine engine2;
                            
                                QQmlComponent component(&engine2,QUrl(QStringLiteral("qrc:/MainForm.ui.qml")));
                                QObject *object = component.create();
                            
                            
                                engine.rootContext()->setContextProperty(QStringLiteral("obj"), &myClass);
                            
                             
                                engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                            
                                return app.exec();
                            }
                            
                            1 Reply Last reply
                            0
                            • S Offline
                              S Offline
                              Scottish_Jason
                              wrote on last edited by Scottish_Jason
                              #16

                              for anybody with the same questions I managed to get it working by adding a connection in the QML

                              Connections
                                      {
                                          id: conn2
                                          target: obj
                                          ignoreUnknownSignals: true
                                          onPostCodeChanged:
                                          {
                                              t2.text = postCode
                                          }
                                      }
                              

                              Thanks SGaist !

                              1 Reply Last reply
                              0
                              • SGaistS Offline
                                SGaistS Offline
                                SGaist
                                Lifetime Qt Champion
                                wrote on last edited by
                                #17

                                AFAIK, you shouldn't need that:

                                Text
                                {
                                    id: t2
                                    text: obj.postCode
                                }
                                

                                should do what you want automatically through the binding.

                                Interested in AI ? www.idiap.ch
                                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                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