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. How to Invoking QML Methods with c++ and connect(..,signal,...,slot) ?
Forum Updated to NodeBB v4.3 + New Features

How to Invoking QML Methods with c++ and connect(..,signal,...,slot) ?

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
11 Posts 4 Posters 1.7k 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.
  • L Offline
    L Offline
    LeeK
    wrote on last edited by LeeK
    #1

    i want to invoke qml function with c++ and use the signal and slot(QObject::connect).
    i don't want to invokemethod(https://doc.qt.io/qt-5/qtqml-cppintegration-interactqmlfromcpp.html).
    don't use : qqmlengine / QMetaObject::invokeMethod
    only, i use qquickview/connect ...
    please help me.

    Here is the code that I wrote. I think that this is normal working.... why don't work...?
    this code works : qml->cpp.
    This code does not work : cpp->qml

    touch next -> controlEvent in QmltoCppControl.cpp -> case 10: -> nextScreen -> emit SendMsgtoQml_ChangeScreen((QVariant)varData); in QmltoCppControl::nextScreen
    -> and function onChangeScreenQml(msg) in main.qml
    but, doesn't work function onChangeScreenQml(msg) in main.qml

    what is problem... ??
    connect or ... ???

    main.cpp

    #include <QGuiApplication>
    //#include <QQmlApplicationEngine>
    //#include <QApplication>
    
    #include <QQuickView>
    
    #include <QtQml>
    #include <QObject>
    #include "QmltoCppControl.h"
    
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
        QQuickView view;
        QmltoCppControl qmltocppcontrol;
        qmlRegisterType<QmltoCppControl>("QmltoCppControl", 1, 0, "QmltoCppControl");
        view.setSource(QUrl("qrc:/main.qml"));
        QObject *qmlRootObject = (QObject*)view.rootObject();
        QObject::connect(&qmltocppcontrol,SIGNAL(SendMsgtoQml_ChangeScreen(QVariant)), qmlRootObject,SLOT(onChangeScreenQml(QVariant)),Qt::QueuedConnection);
    
        //view.rootContext()->setContextProperty("QmltoCppControl", &qmltocppcontrol);
        view.show();
    
        return app.exec();
    }
    
    

    QmltoCppControl.h

    #ifndef QMLTOCPPCONTROL_H
    #define QMLTOCPPCONTROL_H
    
    #include <QObject>
    #include <iostream>
    #include <QVariant>
    
    class QmltoCppControl: public QObject
    {
        Q_OBJECT
    public:
        explicit QmltoCppControl(QObject *parent = 0);
    
    public:
        Q_INVOKABLE void controlEvent(int id);
    signals:
        void SendMsgtoQml_ChangeScreen(QVariant varData);
    private:
        void exitApp();
        void nextScreen();
    };
    
    #endif // QMLTOCPPCONTROL_H
    
    
    

    QmltoCppControl.cpp

    #include "qmltocppcontrol.h"
    #include "controleventid.h"
    
    QmltoCppControl::QmltoCppControl(QObject *parent)
        :QObject(parent)
    {
    }
    
    void QmltoCppControl::controlEvent(int id)
    {
        std::cout << "void QmltoCppControl::controlEvent id :: "<< id << std::endl;
        switch(id){
        case 0:
        {
            exitApp();
            break;
        }
        case 10:
        {
            testnum++;
            nextScreen();
            break;
        }
        default:
        {
    
        }
        }
    }
    
    void QmltoCppControl::nextScreen()
    {
        std::cout << "void QmltoCppControl::nextScreen() :: "<< std::endl;
        QVariantList varData;
        varData.clear();
        varData << 1;
        emit SendMsgtoQml_ChangeScreen((QVariant)varData);
    }
    
    

    main.qml

    import QtQuick 2.9
    import QmltoCppControl 1.0
    
    Rectangle {
        id: main_rect_id
        x: 0
        y: 0
        width: 1920
        height: 560
        visible: true
    
        property int nScreenId: 0
    
        function onChangeScreenQml(msg) {
            console.log("onChangeScreenQml\n");
            qmltocpp_id.controlEvent(0);    //0 = EVENT_APP_EXIT
        }
    
        QmltoCppControl {
            id: qmltocpp_id
        }
    
        Text {
            id: textid;
            font.pixelSize: 30
            horizontalAlignment: Text.AlignHCenter
            text: qsTr("Hello World")
            anchors.centerIn: parent
        }
    
        Item {
            id: next_item_id
            x: main_rect_id.width/4
            y: 460
            width: main_rect_id.width/4
            height: 100
    
            Text {
                id: next_text_id
                font.pixelSize: 30
                horizontalAlignment: Text.AlignHCenter
                text: qsTr("NEXT")
                anchors.centerIn: parent
            }
    
            MouseArea {
                anchors.fill: parent
                onClicked: {
                    qmltocpp_id.controlEvent(10);    //10 = EVENT_SCREEN_NEXT
                }
            }
    
        }
        Item {
            id: exit_item_id
            x: main_rect_id.width/4*3
            y: 460
            width: main_rect_id.width/4
            height: 100
    
            Text {
                id: exit_text_id
                font.pixelSize: 30
                horizontalAlignment: Text.AlignHCenter
                text: qsTr("EXIT")
                anchors.centerIn: parent
            }
    
            MouseArea {
                anchors.fill: parent
                onClicked: {
                    qmltocpp_id.controlEvent(0);    //0 = EVENT_APP_EXIT
                }
            }
    
        }
    }
    
    
    
    J.HilkJ 1 Reply Last reply
    0
    • Shrinidhi UpadhyayaS Offline
      Shrinidhi UpadhyayaS Offline
      Shrinidhi Upadhyaya
      wrote on last edited by
      #2

      Hi @LeeK , i dont think thats the right way to do it, can you explain me what functionality are you trying to achieve,so that i can help you with an optimal solution.

      And by the way did you have a look into the documentation for Q_PROPERTY?

      Shrinidhi Upadhyaya.
      Upvote the answer(s) that helped you to solve the issue.

      L 1 Reply Last reply
      0
      • L LeeK

        i want to invoke qml function with c++ and use the signal and slot(QObject::connect).
        i don't want to invokemethod(https://doc.qt.io/qt-5/qtqml-cppintegration-interactqmlfromcpp.html).
        don't use : qqmlengine / QMetaObject::invokeMethod
        only, i use qquickview/connect ...
        please help me.

        Here is the code that I wrote. I think that this is normal working.... why don't work...?
        this code works : qml->cpp.
        This code does not work : cpp->qml

        touch next -> controlEvent in QmltoCppControl.cpp -> case 10: -> nextScreen -> emit SendMsgtoQml_ChangeScreen((QVariant)varData); in QmltoCppControl::nextScreen
        -> and function onChangeScreenQml(msg) in main.qml
        but, doesn't work function onChangeScreenQml(msg) in main.qml

        what is problem... ??
        connect or ... ???

        main.cpp

        #include <QGuiApplication>
        //#include <QQmlApplicationEngine>
        //#include <QApplication>
        
        #include <QQuickView>
        
        #include <QtQml>
        #include <QObject>
        #include "QmltoCppControl.h"
        
        int main(int argc, char *argv[])
        {
            QGuiApplication app(argc, argv);
            QQuickView view;
            QmltoCppControl qmltocppcontrol;
            qmlRegisterType<QmltoCppControl>("QmltoCppControl", 1, 0, "QmltoCppControl");
            view.setSource(QUrl("qrc:/main.qml"));
            QObject *qmlRootObject = (QObject*)view.rootObject();
            QObject::connect(&qmltocppcontrol,SIGNAL(SendMsgtoQml_ChangeScreen(QVariant)), qmlRootObject,SLOT(onChangeScreenQml(QVariant)),Qt::QueuedConnection);
        
            //view.rootContext()->setContextProperty("QmltoCppControl", &qmltocppcontrol);
            view.show();
        
            return app.exec();
        }
        
        

        QmltoCppControl.h

        #ifndef QMLTOCPPCONTROL_H
        #define QMLTOCPPCONTROL_H
        
        #include <QObject>
        #include <iostream>
        #include <QVariant>
        
        class QmltoCppControl: public QObject
        {
            Q_OBJECT
        public:
            explicit QmltoCppControl(QObject *parent = 0);
        
        public:
            Q_INVOKABLE void controlEvent(int id);
        signals:
            void SendMsgtoQml_ChangeScreen(QVariant varData);
        private:
            void exitApp();
            void nextScreen();
        };
        
        #endif // QMLTOCPPCONTROL_H
        
        
        

        QmltoCppControl.cpp

        #include "qmltocppcontrol.h"
        #include "controleventid.h"
        
        QmltoCppControl::QmltoCppControl(QObject *parent)
            :QObject(parent)
        {
        }
        
        void QmltoCppControl::controlEvent(int id)
        {
            std::cout << "void QmltoCppControl::controlEvent id :: "<< id << std::endl;
            switch(id){
            case 0:
            {
                exitApp();
                break;
            }
            case 10:
            {
                testnum++;
                nextScreen();
                break;
            }
            default:
            {
        
            }
            }
        }
        
        void QmltoCppControl::nextScreen()
        {
            std::cout << "void QmltoCppControl::nextScreen() :: "<< std::endl;
            QVariantList varData;
            varData.clear();
            varData << 1;
            emit SendMsgtoQml_ChangeScreen((QVariant)varData);
        }
        
        

        main.qml

        import QtQuick 2.9
        import QmltoCppControl 1.0
        
        Rectangle {
            id: main_rect_id
            x: 0
            y: 0
            width: 1920
            height: 560
            visible: true
        
            property int nScreenId: 0
        
            function onChangeScreenQml(msg) {
                console.log("onChangeScreenQml\n");
                qmltocpp_id.controlEvent(0);    //0 = EVENT_APP_EXIT
            }
        
            QmltoCppControl {
                id: qmltocpp_id
            }
        
            Text {
                id: textid;
                font.pixelSize: 30
                horizontalAlignment: Text.AlignHCenter
                text: qsTr("Hello World")
                anchors.centerIn: parent
            }
        
            Item {
                id: next_item_id
                x: main_rect_id.width/4
                y: 460
                width: main_rect_id.width/4
                height: 100
        
                Text {
                    id: next_text_id
                    font.pixelSize: 30
                    horizontalAlignment: Text.AlignHCenter
                    text: qsTr("NEXT")
                    anchors.centerIn: parent
                }
        
                MouseArea {
                    anchors.fill: parent
                    onClicked: {
                        qmltocpp_id.controlEvent(10);    //10 = EVENT_SCREEN_NEXT
                    }
                }
        
            }
            Item {
                id: exit_item_id
                x: main_rect_id.width/4*3
                y: 460
                width: main_rect_id.width/4
                height: 100
        
                Text {
                    id: exit_text_id
                    font.pixelSize: 30
                    horizontalAlignment: Text.AlignHCenter
                    text: qsTr("EXIT")
                    anchors.centerIn: parent
                }
        
                MouseArea {
                    anchors.fill: parent
                    onClicked: {
                        qmltocpp_id.controlEvent(0);    //0 = EVENT_APP_EXIT
                    }
                }
        
            }
        }
        
        
        
        J.HilkJ Offline
        J.HilkJ Offline
        J.Hilk
        Moderators
        wrote on last edited by
        #3

        hi @LeeK said in How to Invoking QML Methods with c++ and connect(..,signal,...,slot) ?:

        I think your issue is this:

        void QmltoCppControl::nextScreen()
        {
        std::cout << "void QmltoCppControl::nextScreen() :: "<< std::endl;
        QVariantList varData;
        varData.clear();
        varData << 1;
        emit SendMsgtoQml_ChangeScreen((QVariant)varData);
        }

        You simply cast (c-style cast) a QvariantList to Qvariant. That can't be a valid QVariant


        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


        Q: What's that?
        A: It's blue light.
        Q: What does it do?
        A: It turns blue.

        1 Reply Last reply
        0
        • Shrinidhi UpadhyayaS Shrinidhi Upadhyaya

          Hi @LeeK , i dont think thats the right way to do it, can you explain me what functionality are you trying to achieve,so that i can help you with an optimal solution.

          And by the way did you have a look into the documentation for Q_PROPERTY?

          L Offline
          L Offline
          LeeK
          wrote on last edited by LeeK
          #4

          @Shrinidhi-Upadhyaya
          Thank you.
          but I already know Q_Property, it isn't what I want.


          @J.Hilk
          Thank you.
          I think it isn't the cast problem.
          But I could be wrong, so I tried what you said.
          It still doesn't work.
          And if it's a problem, the below code should work.
          But that doesn't work either.

          main.cpp

           QObject::connect(&qmltocppcontrol,SIGNAL(SendMsgtoQml_ChangeScreen()), qmlRootObject,SLOT(onChangeScreenQml()),Qt::QueuedConnection);
          

          QmltoCppControl.h

          void SendMsgtoQml_ChangeScreen();
          

          QmltoCppControl.cpp

          emit SendMsgtoQml_ChangeScreen();
          

          qml

          function onChangeScreenQml() {
                  console.log("onChangeScreenQml\n");
                  qmltocpp_id.controlEvent(0);    //0 = EVENT_APP_EXIT
              }
          
          1 Reply Last reply
          0
          • Shrinidhi UpadhyayaS Offline
            Shrinidhi UpadhyayaS Offline
            Shrinidhi Upadhyaya
            wrote on last edited by
            #5

            Hi @LeeK , you can do one thing, you can connect the "SendMsgtoQml_ChangeScreen()" signal to a slot and in that slot you can call your QML function which is in your case "onChangeScreenQml"

            For example:-

            //This is just dummy connect statement

            timer = new QTimer(this);
            
            connect(timer, SIGNAL(timeout()),
                    this, SLOT(dummySlot()));
            
            timer->start(10000);
            

            //This is the slot where you can access your QML Function and object is the one which is pointing to your main.qml which in your case is "qmlRootObject" and "qmlHelloWorld" is a function in main.qml

            void DummyClass::dummySlot() {
            
            qDebug() << "Another Slot";
            
            QMetaObject::invokeMethod(object, "qmlHelloWorld");
            }
            

            You cant directly access any qml function like you have done in you main.cpp,you need to use QMetaObject::invokeMethod(). I dont know whether you can directly connect the signal to the QMetaObject::invokeMethod()!

            Shrinidhi Upadhyaya.
            Upvote the answer(s) that helped you to solve the issue.

            L 1 Reply Last reply
            1
            • KroMignonK Offline
              KroMignonK Offline
              KroMignon
              wrote on last edited by
              #6

              @LeeK I think there a almost more easier way to do what you want!

              in main.cpp

              ...
              int main(int argc, char *argv[])
              {
                  QGuiApplication app(argc, argv);
                  QQuickView view;
                  QmltoCppControl qmltocppcontrol;
                  qmlRegisterType<QmltoCppControl>("QmltoCppControl", 1, 0, "QmltoCppControl");
                  view.setSource(QUrl("qrc:/main.qml"));
                  QObject *qmlRootObject = (QObject*)view.rootObject();
                  view.rootContext()->setContextProperty("QmltoCppControl", &qmltocppcontrol);
                  view.show();
              
                  return app.exec();
              }
              

              For easier code comprension; in QmltoCppControl rename signal void SendMsgtoQml_ChangeScreen(QVariant varData) to void changeScreenRequest(QVariant varData)

              main.qml

              import QtQuick 2.9
              import QmltoCppControl 1.0
              
              Rectangle {
                  id: main_rect_id
                  x: 0
                  y: 0
                  width: 1920
                  height: 560
                  visible: true
              
                  property int nScreenId: 0
              
                 Connections {
                      target: qmltocppcontrol
                     onChangeScreenRequest: {
                          console.log("onChangeScreenQml:" + varData);
                          qmltocpp_id.controlEvent(0);    //0 = EVENT_APP_EXIT
                          }
                  }
              
                  QmltoCppControl {
                      id: qmltocpp_id
                  }
              
                  Text {
                      id: textid;
                      font.pixelSize: 30
                      horizontalAlignment: Text.AlignHCenter
                      text: qsTr("Hello World")
                      anchors.centerIn: parent
                  }
              
                  Item {
                      id: next_item_id
                      x: main_rect_id.width/4
                      y: 460
                      width: main_rect_id.width/4
                      height: 100
              
                      Text {
                          id: next_text_id
                          font.pixelSize: 30
                          horizontalAlignment: Text.AlignHCenter
                          text: qsTr("NEXT")
                          anchors.centerIn: parent
                      }
              
                      MouseArea {
                          anchors.fill: parent
                          onClicked: {
                              qmltocpp_id.controlEvent(10);    //10 = EVENT_SCREEN_NEXT
                          }
                      }
              
                  }
                  Item {
                      id: exit_item_id
                      x: main_rect_id.width/4*3
                      y: 460
                      width: main_rect_id.width/4
                      height: 100
              
                      Text {
                          id: exit_text_id
                          font.pixelSize: 30
                          horizontalAlignment: Text.AlignHCenter
                          text: qsTr("EXIT")
                          anchors.centerIn: parent
                      }
              
                      MouseArea {
                          anchors.fill: parent
                          onClicked: {
                              qmltocpp_id.controlEvent(0);    //0 = EVENT_APP_EXIT
                          }
                      }
              
                  }
              }```

              It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

              1 Reply Last reply
              1
              • Shrinidhi UpadhyayaS Shrinidhi Upadhyaya

                Hi @LeeK , you can do one thing, you can connect the "SendMsgtoQml_ChangeScreen()" signal to a slot and in that slot you can call your QML function which is in your case "onChangeScreenQml"

                For example:-

                //This is just dummy connect statement

                timer = new QTimer(this);
                
                connect(timer, SIGNAL(timeout()),
                        this, SLOT(dummySlot()));
                
                timer->start(10000);
                

                //This is the slot where you can access your QML Function and object is the one which is pointing to your main.qml which in your case is "qmlRootObject" and "qmlHelloWorld" is a function in main.qml

                void DummyClass::dummySlot() {
                
                qDebug() << "Another Slot";
                
                QMetaObject::invokeMethod(object, "qmlHelloWorld");
                }
                

                You cant directly access any qml function like you have done in you main.cpp,you need to use QMetaObject::invokeMethod(). I dont know whether you can directly connect the signal to the QMetaObject::invokeMethod()!

                L Offline
                L Offline
                LeeK
                wrote on last edited by LeeK
                #7

                @Shrinidhi-Upadhyaya
                Thank you.
                but, doesn't work .. T.T
                I tried the way you taught me.
                If "invokeMethod" is called directly from main as below, it works normally.

                main.cpp

                #include <QGuiApplication>
                #include <QQuickView>
                #include <QObject>
                #include <QtQml>
                #include <QQmlContext>
                #include "QmltoCppControl.h"
                
                int main(int argc, char *argv[])
                {
                #if defined(Q_OS_WIN)
                    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
                #endif
                
                    QGuiApplication app(argc, argv);
                    QQuickView view;
                    QmltoCppControl qmltocppcontrol;
                    qmlRegisterType<QmltoCppControl>("QmltoCppControl", 1, 0, "QmltoCppControl");
                    view.setSource(QUrl("qrc:/main.qml"));
                    QObject *qmlRootObject = (QObject*)view.rootObject();
                    view.rootContext()->setContextProperty("QmltoCppControl", &qmltocppcontrol);
                    view.show();
                
                    QVariant returnedValue;
                    QVariant msg = "Hello from C++";
                    QMetaObject::invokeMethod(qmlRootObject, "onChangeScreenQml", Q_RETURN_ARG(QVariant, returnedValue), Q_ARG(QVariant, msg));
                
                    return app.exec();
                }
                

                However, it still doesn't work with signal and slot.
                maybe, this is the QObject problem, but I don't know well... how to use it.
                Could you help me?

                QObject *qmlRootObject = (QObject*)m_obj->rootObject();
                    QMetaObject::invokeMethod(qmlRootObject, "onChangeScreenQml", Q_RETURN_ARG(QVariant, returnedValue), Q_ARG(QVariant, msg));
                

                this is the problem code... the way you taught me.
                main.cpp

                #include <QGuiApplication>
                #include <QQuickView>
                #include <QObject>
                #include <QtQml>
                #include <QQmlContext>
                #include "QmltoCppControl.h"
                
                int main(int argc, char *argv[])
                {
                #if defined(Q_OS_WIN)
                    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
                #endif
                
                    QGuiApplication app(argc, argv);
                    QQuickView view;
                    QmltoCppControl qmltocppcontrol;
                    qmlRegisterType<QmltoCppControl>("QmltoCppControl", 1, 0, "QmltoCppControl");
                    view.setSource(QUrl("qrc:/main.qml"));
                    QObject *qmlRootObject = (QObject*)view.rootObject();
                    view.rootContext()->setContextProperty("QmltoCppControl", &qmltocppcontrol);
                    view.show();
                
                    qmltocppcontrol.m_obj = &view;
                
                    return app.exec();
                }
                

                QmltoCppControl.h

                #ifndef QMLTOCPPCONTROL_H
                #define QMLTOCPPCONTROL_H
                
                #include <QObject>
                #include <iostream>
                #include <QVariant>
                #include <QQuickView>
                #include <QDebug>
                
                //#define QARG(object,returnedValue, msg) QMetaObject::invokeMethod(object, "myQmlFunction", Q_RETURN_ARG(QVariant, returnedValue), Q_ARG(QVariant, msg))
                
                class QmltoCppControl: public QObject
                {
                    Q_OBJECT
                public:
                    explicit QmltoCppControl(QObject *parent = 0);
                
                    void init();
                    QQuickView *m_obj;
                public:
                    Q_INVOKABLE void controlEvent(int id);
                signals:
                    void SendMsgtoQml_ChangeScreen();
                
                
                public slots:
                    void Slot_ChangeScreen();
                
                private:
                    void exitApp();
                    void nextScreen();
                
                    int testnum;
                };
                
                #endif // QMLTOCPPCONTROL_H
                

                QmltoCppControl.cpp

                ...
                QmltoCppControl::QmltoCppControl(QObject *parent)
                    :QObject(parent)
                {
                    connect(this, SIGNAL(SendMsgtoQml_ChangeScreen()), this, SLOT(Slot_ChangeScreen()));
                }
                ...
                void QmltoCppControl::nextScreen()
                {
                    std::cout << "void QmltoCppControl::nextScreen() :: "<< std::endl;
                    emit SendMsgtoQml_ChangeScreen();
                
                }
                
                void QmltoCppControl::Slot_ChangeScreen()
                {
                    qDebug() << "Slot_ChangeScreen()" ;
                    QVariant returnedValue;
                    QVariant msg = "Hello from C++";
                    QObject *qmlRootObject = (QObject*)m_obj->rootObject();
                    QMetaObject::invokeMethod(qmlRootObject, "onChangeScreenQml", Q_RETURN_ARG(QVariant, returnedValue), Q_ARG(QVariant, msg));
                }
                
                

                @KroMignon
                Thank you.
                I tried the way you taught me.
                and i get the below error.
                what is the problem???

                qrc:/main.qml:20:5: QML Connections: Cannot assign to non-existent property "onChangeScreenRequest"
                qrc:/main.qml:21: ReferenceError: qmltocppcontrol is not defined
                qrc:/main.qml:21: ReferenceError: qmltocppcontrol is not defined

                line 20 and 21 is...
                line20 ---> target: qmltocppcontrol
                line21 ---> onChangeScreenRequest: {

                and current, i try to the google search continually...

                ~~wow... ~~
                I am solving it a little bit. However, another problem came out..................omg...

                qrc:/main.qml:28: ReferenceError: varData is not defined

                Connections {
                        target: qmltocpp_id
                        onChangeScreenRequest: {
                            console.log("onChangeScreenQml:" + varData);
                            qmltocpp_id.controlEvent(0);    //0 = EVENT_APP_EXIT
                        }
                    }
                

                varData is parameter about signal ...
                i want to use the below parameter of code..

                void QmltoCppControl::nextScreen()
                {
                    std::cout << "void QmltoCppControl::nextScreen() :: "<< std::endl;
                    QVariantList varData;
                    varData.clear();
                    varData << "test";
                    emit changeScreenRequest((QVariant)varData);
                
                }
                

                wow.... solved it!!!
                Thanks @KroMignon !! And thanks to everyone who helped!!!!

                KroMignonK 1 Reply Last reply
                0
                • L LeeK

                  @Shrinidhi-Upadhyaya
                  Thank you.
                  but, doesn't work .. T.T
                  I tried the way you taught me.
                  If "invokeMethod" is called directly from main as below, it works normally.

                  main.cpp

                  #include <QGuiApplication>
                  #include <QQuickView>
                  #include <QObject>
                  #include <QtQml>
                  #include <QQmlContext>
                  #include "QmltoCppControl.h"
                  
                  int main(int argc, char *argv[])
                  {
                  #if defined(Q_OS_WIN)
                      QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
                  #endif
                  
                      QGuiApplication app(argc, argv);
                      QQuickView view;
                      QmltoCppControl qmltocppcontrol;
                      qmlRegisterType<QmltoCppControl>("QmltoCppControl", 1, 0, "QmltoCppControl");
                      view.setSource(QUrl("qrc:/main.qml"));
                      QObject *qmlRootObject = (QObject*)view.rootObject();
                      view.rootContext()->setContextProperty("QmltoCppControl", &qmltocppcontrol);
                      view.show();
                  
                      QVariant returnedValue;
                      QVariant msg = "Hello from C++";
                      QMetaObject::invokeMethod(qmlRootObject, "onChangeScreenQml", Q_RETURN_ARG(QVariant, returnedValue), Q_ARG(QVariant, msg));
                  
                      return app.exec();
                  }
                  

                  However, it still doesn't work with signal and slot.
                  maybe, this is the QObject problem, but I don't know well... how to use it.
                  Could you help me?

                  QObject *qmlRootObject = (QObject*)m_obj->rootObject();
                      QMetaObject::invokeMethod(qmlRootObject, "onChangeScreenQml", Q_RETURN_ARG(QVariant, returnedValue), Q_ARG(QVariant, msg));
                  

                  this is the problem code... the way you taught me.
                  main.cpp

                  #include <QGuiApplication>
                  #include <QQuickView>
                  #include <QObject>
                  #include <QtQml>
                  #include <QQmlContext>
                  #include "QmltoCppControl.h"
                  
                  int main(int argc, char *argv[])
                  {
                  #if defined(Q_OS_WIN)
                      QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
                  #endif
                  
                      QGuiApplication app(argc, argv);
                      QQuickView view;
                      QmltoCppControl qmltocppcontrol;
                      qmlRegisterType<QmltoCppControl>("QmltoCppControl", 1, 0, "QmltoCppControl");
                      view.setSource(QUrl("qrc:/main.qml"));
                      QObject *qmlRootObject = (QObject*)view.rootObject();
                      view.rootContext()->setContextProperty("QmltoCppControl", &qmltocppcontrol);
                      view.show();
                  
                      qmltocppcontrol.m_obj = &view;
                  
                      return app.exec();
                  }
                  

                  QmltoCppControl.h

                  #ifndef QMLTOCPPCONTROL_H
                  #define QMLTOCPPCONTROL_H
                  
                  #include <QObject>
                  #include <iostream>
                  #include <QVariant>
                  #include <QQuickView>
                  #include <QDebug>
                  
                  //#define QARG(object,returnedValue, msg) QMetaObject::invokeMethod(object, "myQmlFunction", Q_RETURN_ARG(QVariant, returnedValue), Q_ARG(QVariant, msg))
                  
                  class QmltoCppControl: public QObject
                  {
                      Q_OBJECT
                  public:
                      explicit QmltoCppControl(QObject *parent = 0);
                  
                      void init();
                      QQuickView *m_obj;
                  public:
                      Q_INVOKABLE void controlEvent(int id);
                  signals:
                      void SendMsgtoQml_ChangeScreen();
                  
                  
                  public slots:
                      void Slot_ChangeScreen();
                  
                  private:
                      void exitApp();
                      void nextScreen();
                  
                      int testnum;
                  };
                  
                  #endif // QMLTOCPPCONTROL_H
                  

                  QmltoCppControl.cpp

                  ...
                  QmltoCppControl::QmltoCppControl(QObject *parent)
                      :QObject(parent)
                  {
                      connect(this, SIGNAL(SendMsgtoQml_ChangeScreen()), this, SLOT(Slot_ChangeScreen()));
                  }
                  ...
                  void QmltoCppControl::nextScreen()
                  {
                      std::cout << "void QmltoCppControl::nextScreen() :: "<< std::endl;
                      emit SendMsgtoQml_ChangeScreen();
                  
                  }
                  
                  void QmltoCppControl::Slot_ChangeScreen()
                  {
                      qDebug() << "Slot_ChangeScreen()" ;
                      QVariant returnedValue;
                      QVariant msg = "Hello from C++";
                      QObject *qmlRootObject = (QObject*)m_obj->rootObject();
                      QMetaObject::invokeMethod(qmlRootObject, "onChangeScreenQml", Q_RETURN_ARG(QVariant, returnedValue), Q_ARG(QVariant, msg));
                  }
                  
                  

                  @KroMignon
                  Thank you.
                  I tried the way you taught me.
                  and i get the below error.
                  what is the problem???

                  qrc:/main.qml:20:5: QML Connections: Cannot assign to non-existent property "onChangeScreenRequest"
                  qrc:/main.qml:21: ReferenceError: qmltocppcontrol is not defined
                  qrc:/main.qml:21: ReferenceError: qmltocppcontrol is not defined

                  line 20 and 21 is...
                  line20 ---> target: qmltocppcontrol
                  line21 ---> onChangeScreenRequest: {

                  and current, i try to the google search continually...

                  ~~wow... ~~
                  I am solving it a little bit. However, another problem came out..................omg...

                  qrc:/main.qml:28: ReferenceError: varData is not defined

                  Connections {
                          target: qmltocpp_id
                          onChangeScreenRequest: {
                              console.log("onChangeScreenQml:" + varData);
                              qmltocpp_id.controlEvent(0);    //0 = EVENT_APP_EXIT
                          }
                      }
                  

                  varData is parameter about signal ...
                  i want to use the below parameter of code..

                  void QmltoCppControl::nextScreen()
                  {
                      std::cout << "void QmltoCppControl::nextScreen() :: "<< std::endl;
                      QVariantList varData;
                      varData.clear();
                      varData << "test";
                      emit changeScreenRequest((QVariant)varData);
                  
                  }
                  

                  wow.... solved it!!!
                  Thanks @KroMignon !! And thanks to everyone who helped!!!!

                  KroMignonK Offline
                  KroMignonK Offline
                  KroMignon
                  wrote on last edited by
                  #8

                  @LeeK You are very confusing in your comments, I don't really understand your problem...

                  What do you want to do???

                  As I have understand, you want to connect a object created from C++ with a QML code. Is this correct?
                  For me:

                  • the c++ object was qmltocppcontrol created in main.cpp
                  • the QML instance was qmltocpp_id created in main.qml

                  If this is not what you want to do, please be clear in what is to task you want to do!

                  regards

                  It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                  L 1 Reply Last reply
                  0
                  • J.HilkJ Offline
                    J.HilkJ Offline
                    J.Hilk
                    Moderators
                    wrote on last edited by
                    #9
                    //main.cpp
                    #include <QApplication>
                    #include <QQmlApplicationEngine>
                    
                    #include "myclass.h"
                    
                    int main(int argc, char *argv[])
                    {
                        QApplication app(argc, argv);
                    
                        QQmlApplicationEngine engine;
                    
                        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                        if (engine.rootObjects().isEmpty())
                            return -1;
                    
                        myClass mClass;
                        QObject *rootElement = engine.rootObjects().first();
                    
                        QObject::connect(&mClass,SIGNAL(mySignal(QVariant)), rootElement, SLOT(qmlFunction(QVariant)));
                    
                        return app.exec();
                    }
                    
                    
                    //myClass.h
                    #ifndef MYCLASS_H
                    #define MYCLASS_H
                    
                    #include <QObject>
                    #include <QVariant>
                    #include <QTimer>
                    #include <QTime>
                    
                    class myClass : public QObject
                    {
                        Q_OBJECT
                    public:
                        explicit myClass(QObject *parent = nullptr) :QObject(parent)
                        {
                            QTimer *t = new QTimer(this);
                    
                            connect(t, &QTimer::timeout, this, [=]()->void{
                                emit mySignal(QVariant::fromValue(QTime::currentTime().toString("hh.mm.ss")));
                            });
                    
                            t->start(1000);
                        }
                    
                    signals:
                        void mySignal(QVariant msg);
                    
                    public slots:
                    };
                    
                    #endif // MYCLASS_H
                    
                    
                    //main.qml
                    import QtQuick 2.12
                    import QtQuick.Window 2.2
                    
                    Window
                    {
                        id:rootWindow
                        width: 400
                        height: 250
                    
                        visible:  true
                    
                        function qmlFunction(msg) {
                            console.log(msg)
                            myText.text = msg;
                        }
                    
                        Text {
                            id:myText
                            anchors.centerIn: parent
                            text: qsTr("text")
                        }
                    }
                    
                    

                    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                    Q: What's that?
                    A: It's blue light.
                    Q: What does it do?
                    A: It turns blue.

                    1 Reply Last reply
                    0
                    • Shrinidhi UpadhyayaS Offline
                      Shrinidhi UpadhyayaS Offline
                      Shrinidhi Upadhyaya
                      wrote on last edited by
                      #10

                      Hi @LeeK , i dont know how you tried it, there is no way in which it will not work, i guess you must have missed passing a paramter or some silly mistakes. And the code which you have posted is completely different from what you had asked, you actually wanted to connect a signal to a function in qml and when i asked you have seen the Q_PROPERTY documentation, you told me yes you have seen, if you had seen Q_PROPERTY documentation you would even stumbled upon Connections documentation, please be clear on what is your requirement.

                      Shrinidhi Upadhyaya.
                      Upvote the answer(s) that helped you to solve the issue.

                      1 Reply Last reply
                      0
                      • KroMignonK KroMignon

                        @LeeK You are very confusing in your comments, I don't really understand your problem...

                        What do you want to do???

                        As I have understand, you want to connect a object created from C++ with a QML code. Is this correct?
                        For me:

                        • the c++ object was qmltocppcontrol created in main.cpp
                        • the QML instance was qmltocpp_id created in main.qml

                        If this is not what you want to do, please be clear in what is to task you want to do!

                        regards

                        L Offline
                        L Offline
                        LeeK
                        wrote on last edited by LeeK
                        #11

                        @KroMignon
                        Thank you.

                        I am sorry for the confusion in my comments.
                        I solved the problem in the way that you suggested.
                        Thank you.

                        @J-Hilk
                        Thank you.
                        I solved the problem. but, additionally i will try to the way that you suggested.

                        @Shrinidhi-Upadhyaya
                        Thank you.
                        I don't know what you mean.
                        I did not know the part of the mistake or the wrong parameter you mentioned. So I asked the question.
                        I have already solved this problem with the help of others.

                        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