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. Problem connecting signal/slot between 2 new QML type instances

Problem connecting signal/slot between 2 new QML type instances

Scheduled Pinned Locked Moved Solved QML and Qt Quick
5 Posts 3 Posters 1.8k Views 3 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.
  • F Offline
    F Offline
    FrancoisPicard
    wrote on last edited by
    #1

    Hi

    I am struggling a bit with a signal/slot connection between 2 new QML type instances. I am not sure I am doing things properly and I have been through the net for 2 days without finding proper solution. You may be able to help. I am working with Qt 5.8.

    I have created 2 new QML types, let's say ObjectA and ObjectB. For now, neither of them is used to display anything so they only inherit from QObject.
    I have created a basic application window, in QML, including only one button. I want the button to call a method from the ObjectA-related class (Q_INVOKABLE). Then I want the method to emit a signal connected to a slot declared by the ObjectB-related class. Ultimately, I want the ObjectB-related class to inherit from QQuickPaintedItem, so that the signal emission generates an visual update in the GUI.
    The connection between the signal and the slot is done in the main, which seems to be the problem, even if I saw some examples doing so on the net.

    Here is my code:

    ObjectA.qml (replace "A" by "B" to get ObjectB.qml)

    import ObjA 1.0
    import QtQuick 2.1
    
    ObjectA
    {
    }
    

    main.qml

    import QtQuick 2.7
    import QtQuick.Controls 2.0
    import QtQuick.Layouts 1.0
    import ObjA 1.0
    import ObjB 1.0
    
    ApplicationWindow {
      visible: true
      width: 640
      height: 480
      title: qsTr("Hello World")
    
      Button {
          id: button
          x: 270
          y: 206
          text: qsTr("Activate")
    
          onClicked: {
            oA.activateBFromA()
          }
      }
    
      ObjectA {
          id: oA
      }
    
      ObjectB {
          id: oB
      }
    }
    

    ObjectA.h

    #ifndef OBJECTA_H
    #define OBJECTA_H
    
    #include <QObject>
    #include <QDebug>
    
    class objectA : public QObject
    {
      Q_OBJECT
    
    public:
      objectA(QObject *parent = 0);
      ~objectA();
    
      Q_INVOKABLE void activateBFromA();
    
    signals:
      void bActivated (const int& value);
    };
    
    #endif
    

    ObjectA.cpp

    #include "ObjectA.h"
    #include <QDebug>
    
    objectA::objectA(QObject *parent)
      : QObject(parent)
    {
    }
    
    objectA::~objectA()
    {
    }
    
    void objectA::activateBFromA()
    {
      qDebug() << "Emit from A";
      emit this->bActivated(5);
    }
    

    ObjectB.h

    #ifndef OBJECTB_H
    #define OBJECTB_H
    
    #include <QObject>
    #include <QDebug>
    
    class objectB : public QObject
    {
      Q_OBJECT
    
    public:
      objectB(QObject *parent = 0);
      ~objectB();
    
    public slots:
      void onBActivated (const int& value)
      {
        for (int i = 0; i < value; i++)
          qDebug() << "Activation (from B) !";
      }
    };
    
    #endif
    

    ObjectB.cpp

    #include "ObjectB.h"
    #include <QDebug>
    
    objectB::objectB(QObject *parent)
      : QObject(parent)
    {
    }
    
    objectB::~objectB()
    {
    }
    

    and finally main.cpp

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlComponent>
    
    #include "ObjectA.h"
    #include "ObjectB.h"
    
    int main(int argc, char *argv[])
    {
      QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
      QGuiApplication app(argc, argv);
    
      QQmlApplicationEngine engine;
    
      qmlRegisterType<objectA>("ObjA", 1,0, "ObjectA");
      qmlRegisterType<objectB>("ObjB", 1,0, "ObjectB");
    
      QQmlComponent componentA(&engine, QUrl("qrc:ObjectA.qml"));
      objectA* oA = qobject_cast<objectA*>(componentA.create());
    
      QQmlComponent componentB(&engine, QUrl("qrc:ObjectB.qml"));
      objectB* oB = qobject_cast<objectB*>(componentB.create());
    
      QObject::connect(oA, &objectA::bActivated, oB, &objectB::onBActivated);
    
      engine.load(QUrl(QLatin1String("qrc:/main.qml")));
    
      return app.exec();
    }
    

    My console only displays: "Emit from A", it seems that the connection is not working.
    Any help appreciated, thanks a lot in advance.

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

      Hi and welcome to devnet,

      The objects you are connecting in your main function are not the same as the one your create in your main.qml file.

      You need to first load main.qml, then search for the objects and only after that connect them.

      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
      1
      • ? Offline
        ? Offline
        A Former User
        wrote on last edited by
        #3

        Hi! Either do it like @SGaist suggested, or connect the objects inside your QML file:

        myobjecta.h

        #ifndef MYOBJECTA_H
        #define MYOBJECTA_H
        
        #include <QObject>
        
        class MyObjectA : public QObject
        {
            Q_OBJECT
        public:
            explicit MyObjectA(QObject *parent = nullptr);
            Q_INVOKABLE void doIt() { emit doItCalled(); }
        
        signals:
            void doItCalled();
        };
        
        #endif // MYOBJECTA_H
        

        myobjectb.h

        #ifndef MYOBJECTB_H
        #define MYOBJECTB_H
        
        #include <QObject>
        #include <QDebug>
        
        class MyObjectB : public QObject
        {
            Q_OBJECT
        public:
            explicit MyObjectB(QObject *parent = nullptr);
        
        public slots:
            void doItSlot() {
                qDebug() << "hello";
            }
        };
        
        #endif // MYOBJECTB_H
        

        main.cpp

        #include <QGuiApplication>
        #include <QQmlApplicationEngine>
        #include <QQmlComponent>
        
        #include <myobjecta.h>
        #include <myobjectb.h>
        
        int main(int argc, char *argv[])
        {
            QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
            QGuiApplication app(argc, argv);
        
            qmlRegisterType<MyObjectA>("io.qt.forum", 1, 0, "MyObjectA");
            qmlRegisterType<MyObjectB>("io.qt.forum", 1, 0, "MyObjectB");
        
            QQmlApplicationEngine engine;
            engine.load(QUrl(QLatin1String("qrc:/main.qml")));
        
            return app.exec();
        }
        

        main.qml

        import QtQuick 2.7
        import QtQuick.Controls 2.0
        import QtQuick.Layouts 1.0
        
        import io.qt.forum 1.0
        
        ApplicationWindow {
            visible: true
            width: 640
            height: 480
        
            MyObjectA {
                id: objA
                onDoItCalled: objB.doItSlot() 
            }
        
            MyObjectB {
                id: objB
            }
        
            Button {
                anchors.centerIn: parent
                text: "Click me"
                onClicked: objA.doIt()
            }
        }
        
        1 Reply Last reply
        2
        • ? Offline
          ? Offline
          A Former User
          wrote on last edited by
          #4

          Oh, BTW, the forum thread Calling JS functions in loaded components from C++ contains an example for how to find QML-objects from the C++ side.

          1 Reply Last reply
          2
          • F Offline
            F Offline
            FrancoisPicard
            wrote on last edited by
            #5

            1000 thanks @SGaist and @Wieland !!! I tried both solutions everything works.

            For the sake of others, here is then the modifications in my example if I am adopting the first solution:

            ObjectA.qml (replace "A" by "B" to get ObjectB.qml)

            import ObjA 1.0
            import QtQuick 2.1
            
            ObjectA
            {
                objectName: "objA_id"    // do not forget the quotes...
            }
            

            ObjectB.h

            ...
            public slots:
              void activateB (const int& value)
              {
                for (int i = 0; i < value; i++)
                  qDebug() << "Activation (from B) !";
              }
            ...
            

            main.cpp

            int main(int argc, char *argv[])
            {
              QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
              QGuiApplication app(argc, argv);
            
              qmlRegisterType<objectA>("ObjA", 1,0, "ObjectA");
              qmlRegisterType<objectB>("ObjB", 1,0, "ObjectB");
            
              QQmlApplicationEngine engine;
              engine.load(QUrl(QLatin1String("qrc:/main.qml")));
            
              objectA* oA = qobject_cast<objectA*>(engine.rootObjects().first()->findChild<QObject*>("objA_id"));
              objectB* oB = qobject_cast<objectB*>(engine.rootObjects().first()->findChild<QObject*>("objB_id"));
            
              QObject::connect(oA, &objectA::bActivated, oB, &objectB::activateB);
            
              return app.exec();
            }
            

            Thanks again guys. That was great help.

            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