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 catch a signal emitted from cpp class in Qml ?
Forum Updated to NodeBB v4.3 + New Features

How to catch a signal emitted from cpp class in Qml ?

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
21 Posts 4 Posters 9.4k 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.
  • sneubertS Offline
    sneubertS Offline
    sneubert
    wrote on last edited by
    #2

    QQuick creates signal handlers for your cpp classes like:

    HandleTextField {
            id: testsignal
            onSetTextField: { //your code}
        }
    

    http://doc.qt.io/qt-5/qtqml-cppintegration-exposecppattributes.html#exposing-signals

    1 Reply Last reply
    2
    • J Offline
      J Offline
      Jagh
      wrote on last edited by
      #3

      You have 2 different objects of class HandleTextField in your code(one created in main(), the other in Qml), and you connect/send a signal from different ones. For your code to work, you have to connect the HandleTextField that you created in your Qml code, and you dont need the object in main() anymore, you don't do anything with it anyway.

      In Qmal this would look like:

      HandleTextField {
         id: testsignal
         onSetTextField: {
            console.log("signal called")
         }
      }
      
      Naveen_DN 2 Replies Last reply
      2
      • J Jagh

        You have 2 different objects of class HandleTextField in your code(one created in main(), the other in Qml), and you connect/send a signal from different ones. For your code to work, you have to connect the HandleTextField that you created in your Qml code, and you dont need the object in main() anymore, you don't do anything with it anyway.

        In Qmal this would look like:

        HandleTextField {
           id: testsignal
           onSetTextField: {
              console.log("signal called")
           }
        }
        
        Naveen_DN Offline
        Naveen_DN Offline
        Naveen_D
        wrote on last edited by
        #4

        @Jagh but if i dont create a object of handletextfield in main.cpp how can i connect the signal and slot ?

        Naveen_D

        J 1 Reply Last reply
        0
        • J Jagh

          You have 2 different objects of class HandleTextField in your code(one created in main(), the other in Qml), and you connect/send a signal from different ones. For your code to work, you have to connect the HandleTextField that you created in your Qml code, and you dont need the object in main() anymore, you don't do anything with it anyway.

          In Qmal this would look like:

          HandleTextField {
             id: testsignal
             onSetTextField: {
                console.log("signal called")
             }
          }
          
          Naveen_DN Offline
          Naveen_DN Offline
          Naveen_D
          wrote on last edited by
          #5

          @Jagh You mean to say the following part is not required in main.cpp ??

          HandleTextField handleTextField;
          
              QObject *topLevel = engine.rootObjects().value(0);
              QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
          
          //    QObject::connect(window, SIGNAL(submitTextField()),
          //                         &handleTextField, SLOT(handleSubmitTextField()));
          
              QObject::connect(&handleTextField, SIGNAL(setTextField()),
                                   window, SLOT(setTextField()));
          

          only i need to emit the signal and catch it in qml..in the same way as you have done ?

          Naveen_D

          1 Reply Last reply
          0
          • Naveen_DN Naveen_D

            @Jagh but if i dont create a object of handletextfield in main.cpp how can i connect the signal and slot ?

            J Offline
            J Offline
            Jagh
            wrote on last edited by
            #6

            @Naveen_D

            1. You connect objects, not classes with signal-slot mechanism. So if you connect one object HandleTextField to something, this connection will not automatically transfer to other objects of the same class.
            2. Exactly, that part is not required, and in fact, it doesn't do anything. Connections for one object in your C++ code don't transfer to unrelated objects in QML.
            3. Yep, for each signal an object emits, QML exposes a property named on<SignalName>, in your case this would be onSetTextField. You can set this property as i have done, but AFAIK it should also be possible to set it from outside, having
            testsignal.onSetTextField: {
               console.log("signal called")
            }
            

            somewhere in your Qml should suffice

            Naveen_DN 1 Reply Last reply
            0
            • J Jagh

              @Naveen_D

              1. You connect objects, not classes with signal-slot mechanism. So if you connect one object HandleTextField to something, this connection will not automatically transfer to other objects of the same class.
              2. Exactly, that part is not required, and in fact, it doesn't do anything. Connections for one object in your C++ code don't transfer to unrelated objects in QML.
              3. Yep, for each signal an object emits, QML exposes a property named on<SignalName>, in your case this would be onSetTextField. You can set this property as i have done, but AFAIK it should also be possible to set it from outside, having
              testsignal.onSetTextField: {
                 console.log("signal called")
              }
              

              somewhere in your Qml should suffice

              Naveen_DN Offline
              Naveen_DN Offline
              Naveen_D
              wrote on last edited by Naveen_D
              #7

              @Jagh thank you for your reply...
              now i have removed that part from main.cpp...but now also when i emit a signal i am not able to catch it in Qml...
              the way i am registering that handletextfiled class, is it correct ...???

              here is the code...

              main.qml

              import QtQuick 2.3
              import QtQuick.Window 2.2
              import QtQuick.Controls 1.2
              import com.handletextfield 1.0
              
              Window {
                  visible: true
                  width: 360
                  height: 360
              
                  HandleTextField {
                      id: testsignal
                      onSetTextField: {
                          console.log("Signal catched successfully...")
                      }
                  }
              }
              

              main.cpp

              #include <QGuiApplication>
              #include <QQmlApplicationEngine>
              #include <QQuickWindow>
              #include <QQmlContext>
              
              #include "handletextfield.h"
              
              int main(int argc, char *argv[])
              {
                  QGuiApplication app(argc, argv);
                  qmlRegisterType<HandleTextField>("com.handletextfield",1,0,"HandleTextField");
              
                  QQmlApplicationEngine engine;
                  engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
              
                  return app.exec();
              }
              
              

              handletextfield.cpp

              #include "handletextfield.h"
              
              HandleTextField::HandleTextField(QObject *parent) :
                  QObject(parent)
              {
                  handleSubmitTextField();
              }
              
              void HandleTextField::handleSubmitTextField()
              {
                  qDebug() << "c++: HandleTextField::handleSubmitTextField:" << endl;
                  emit setTextField();
                  qDebug()<<"Signal emitted..."<<endl;
              }
              
              

              Naveen_D

              1 Reply Last reply
              0
              • J Offline
                J Offline
                Jagh
                wrote on last edited by
                #8

                You are sending signal way too early, before there was any chance for a connection to be established. In constructor the object hasn't been fully initialized yet, in particular, the QML-interpreter hadn't had a chance to initialize the object's properties from QML side yet.

                Naveen_DN 1 Reply Last reply
                0
                • J Jagh

                  You are sending signal way too early, before there was any chance for a connection to be established. In constructor the object hasn't been fully initialized yet, in particular, the QML-interpreter hadn't had a chance to initialize the object's properties from QML side yet.

                  Naveen_DN Offline
                  Naveen_DN Offline
                  Naveen_D
                  wrote on last edited by
                  #9

                  @Jagh Okay...
                  then when should i emit a signal...so that i can catch over there...calling my function in constructor is the mistake...??

                  Naveen_D

                  1 Reply Last reply
                  0
                  • J Offline
                    J Offline
                    Jagh
                    wrote on last edited by
                    #10

                    I changed your code a bit so that handleSubmitTextField() is called in more appropriate time(actually i just added a Button and called this function in onClicked handler), and the signal handler was successfully called.

                    To when: anytime between QML object initialization (implement Component.onCompleted if you want to catch it) and object destruction is ok.

                    Naveen_DN 2 Replies Last reply
                    0
                    • J Jagh

                      I changed your code a bit so that handleSubmitTextField() is called in more appropriate time(actually i just added a Button and called this function in onClicked handler), and the signal handler was successfully called.

                      To when: anytime between QML object initialization (implement Component.onCompleted if you want to catch it) and object destruction is ok.

                      Naveen_DN Offline
                      Naveen_DN Offline
                      Naveen_D
                      wrote on last edited by
                      #11

                      @Jagh can you please post the code so that i will get a clear picture of what i need to do...thanks...

                      Naveen_D

                      1 Reply Last reply
                      0
                      • J Jagh

                        I changed your code a bit so that handleSubmitTextField() is called in more appropriate time(actually i just added a Button and called this function in onClicked handler), and the signal handler was successfully called.

                        To when: anytime between QML object initialization (implement Component.onCompleted if you want to catch it) and object destruction is ok.

                        Naveen_DN Offline
                        Naveen_DN Offline
                        Naveen_D
                        wrote on last edited by
                        #12

                        @Jagh I tried the way u told by adding a button and calling the handler...it worked thanks...\o/

                        Naveen_D

                        1 Reply Last reply
                        0
                        • J Offline
                          J Offline
                          Jagh
                          wrote on last edited by
                          #13

                          And if you really want to execute some code as soon as possible and have a guarantee that a QML object was fully initialized by the time your code is running, do it in Component.onCompleted handler of that object.

                          1 Reply Last reply
                          0
                          • Naveen_DN Offline
                            Naveen_DN Offline
                            Naveen_D
                            wrote on last edited by
                            #14

                            Ok thanks... i will try that also...:-)

                            Naveen_D

                            1 Reply Last reply
                            0
                            • Naveen_DN Offline
                              Naveen_DN Offline
                              Naveen_D
                              wrote on last edited by
                              #15

                              Hi i have doubt regarding catching a signal emitted from c++ file
                              if there are more than 2 .qml files does it catch the signal ?
                              for ex, i have one .cpp and 4 .qml such as mainform.qml,radio.qml,music.qml,setting .qml
                              so if i emit a signal and try to catch it in setting.qml does it work ??

                              Naveen_D

                              V 1 Reply Last reply
                              0
                              • Naveen_DN Naveen_D

                                Hi i have doubt regarding catching a signal emitted from c++ file
                                if there are more than 2 .qml files does it catch the signal ?
                                for ex, i have one .cpp and 4 .qml such as mainform.qml,radio.qml,music.qml,setting .qml
                                so if i emit a signal and try to catch it in setting.qml does it work ??

                                V Offline
                                V Offline
                                VincentLiu
                                wrote on last edited by
                                #16

                                @Naveen_D
                                Yes it works. I have tried before.

                                Naveen_DN 1 Reply Last reply
                                1
                                • V VincentLiu

                                  @Naveen_D
                                  Yes it works. I have tried before.

                                  Naveen_DN Offline
                                  Naveen_DN Offline
                                  Naveen_D
                                  wrote on last edited by
                                  #17

                                  @VincentLiu but in my case it is not working....

                                  my code is...
                                  this .cpp where i am emitting signal..

                                  if(!WordList.isEmpty())
                                              {
                                                  WordList.removeFirst();
                                                  WordList.removeLast();
                                  //                QMessageBox m_popupmsgbox;
                                  //                m_popupmsgbox.setWindowTitle("Voice Recognizer");
                                  //                Phoneme=WordList.join(" ");
                                  //                qDebug()<<"firstword"<<Phoneme<<endl;
                                  //                QSpacerItem* horizontalSpacer = new QSpacerItem(500, 100, QSizePolicy::Minimum, QSizePolicy::Expanding);
                                  //                m_popupmsgbox.setText( Phoneme);
                                  //                QGridLayout* layout = (QGridLayout*)m_popupmsgbox.layout();
                                  //                layout->addItem(horizontalSpacer, layout->rowCount(), 0, 1, layout->columnCount());
                                  //                m_popupmsgbox.exec();
                                  //                emitSignalFunc();
                                  //                m_emitSignal= new EmitSignalClass;
                                  //                m_emitSignal->emitSignalmethod();
                                                  VoiceRecognition voice;
                                                  voice.playmusicsignal();
                                              }
                                              else
                                              {
                                                  qDebug()<<"List is empty"<<endl;
                                              }
                                  

                                  my .qml is

                                  Rectangle{
                                              id:voicerecRect
                                              width: settings_main_rect.width/5
                                              height: settings_main_rect.height/4
                                              color: "transparent"
                                  
                                              VoiceRecognition {
                                                  id: voiceRecognizer
                                                  onPlaymusicsignal: {
                                                      console.log("Signal catched...")
                                                  }
                                              }
                                  
                                              Image {
                                                  id: vr_image
                                                  source: "qrc:/AppbarIcon.png"
                                                  //source: "qrc:/Voice-Recoder-icon.png"
                                                  width: parent.width-10
                                                  height: parent.height-10
                                                  smooth: true
                                                  fillMode: Image.PreserveAspectFit
                                                  anchors.centerIn: parent
                                  
                                                  Text {
                                                      id: vrtext
                                                      anchors.top: parent.bottom
                                                      anchors.horizontalCenter: vr_image.horizontalCenter
                                                      text: qsTr("Voice Recorder")
                                                      color: "white"
                                                      font.pixelSize: parent.height * (2 / 9)
                                  
                                                  }
                                                  MouseArea {
                                                      anchors.fill: parent
                                                      onClicked: {
                                                          //popup.open()
                                                          voicerecRect.color = 'green'
                                                          voiceRecognizer.vstartVoiceRecognition()
                                                      }
                                                  }
                                              }
                                          }
                                      }
                                  
                                  

                                  i have registered the class using qmlregister and i am using signal handler to catch the signal...

                                  Naveen_D

                                  V 1 Reply Last reply
                                  0
                                  • Naveen_DN Naveen_D

                                    @VincentLiu but in my case it is not working....

                                    my code is...
                                    this .cpp where i am emitting signal..

                                    if(!WordList.isEmpty())
                                                {
                                                    WordList.removeFirst();
                                                    WordList.removeLast();
                                    //                QMessageBox m_popupmsgbox;
                                    //                m_popupmsgbox.setWindowTitle("Voice Recognizer");
                                    //                Phoneme=WordList.join(" ");
                                    //                qDebug()<<"firstword"<<Phoneme<<endl;
                                    //                QSpacerItem* horizontalSpacer = new QSpacerItem(500, 100, QSizePolicy::Minimum, QSizePolicy::Expanding);
                                    //                m_popupmsgbox.setText( Phoneme);
                                    //                QGridLayout* layout = (QGridLayout*)m_popupmsgbox.layout();
                                    //                layout->addItem(horizontalSpacer, layout->rowCount(), 0, 1, layout->columnCount());
                                    //                m_popupmsgbox.exec();
                                    //                emitSignalFunc();
                                    //                m_emitSignal= new EmitSignalClass;
                                    //                m_emitSignal->emitSignalmethod();
                                                    VoiceRecognition voice;
                                                    voice.playmusicsignal();
                                                }
                                                else
                                                {
                                                    qDebug()<<"List is empty"<<endl;
                                                }
                                    

                                    my .qml is

                                    Rectangle{
                                                id:voicerecRect
                                                width: settings_main_rect.width/5
                                                height: settings_main_rect.height/4
                                                color: "transparent"
                                    
                                                VoiceRecognition {
                                                    id: voiceRecognizer
                                                    onPlaymusicsignal: {
                                                        console.log("Signal catched...")
                                                    }
                                                }
                                    
                                                Image {
                                                    id: vr_image
                                                    source: "qrc:/AppbarIcon.png"
                                                    //source: "qrc:/Voice-Recoder-icon.png"
                                                    width: parent.width-10
                                                    height: parent.height-10
                                                    smooth: true
                                                    fillMode: Image.PreserveAspectFit
                                                    anchors.centerIn: parent
                                    
                                                    Text {
                                                        id: vrtext
                                                        anchors.top: parent.bottom
                                                        anchors.horizontalCenter: vr_image.horizontalCenter
                                                        text: qsTr("Voice Recorder")
                                                        color: "white"
                                                        font.pixelSize: parent.height * (2 / 9)
                                    
                                                    }
                                                    MouseArea {
                                                        anchors.fill: parent
                                                        onClicked: {
                                                            //popup.open()
                                                            voicerecRect.color = 'green'
                                                            voiceRecognizer.vstartVoiceRecognition()
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    
                                    

                                    i have registered the class using qmlregister and i am using signal handler to catch the signal...

                                    V Offline
                                    V Offline
                                    VincentLiu
                                    wrote on last edited by
                                    #18

                                    @Naveen_D
                                    Hi, first of all, I should say that I use different ways to do this. However, according to some similar experience on it. I guess you shouldn't use a new VoiceRecognition object in your .cpp file. I don't think distinct object derived from the same class can communicate this way. Please correct me if I am wrong. Thanks

                                    Naveen_DN 2 Replies Last reply
                                    0
                                    • V VincentLiu

                                      @Naveen_D
                                      Hi, first of all, I should say that I use different ways to do this. However, according to some similar experience on it. I guess you shouldn't use a new VoiceRecognition object in your .cpp file. I don't think distinct object derived from the same class can communicate this way. Please correct me if I am wrong. Thanks

                                      Naveen_DN Offline
                                      Naveen_DN Offline
                                      Naveen_D
                                      wrote on last edited by
                                      #19

                                      @VincentLiu the function in which i am emitting a signal is a global function so i need to create an obj of that class and emit.

                                      Naveen_D

                                      1 Reply Last reply
                                      0
                                      • V VincentLiu

                                        @Naveen_D
                                        Hi, first of all, I should say that I use different ways to do this. However, according to some similar experience on it. I guess you shouldn't use a new VoiceRecognition object in your .cpp file. I don't think distinct object derived from the same class can communicate this way. Please correct me if I am wrong. Thanks

                                        Naveen_DN Offline
                                        Naveen_DN Offline
                                        Naveen_D
                                        wrote on last edited by
                                        #20

                                        @VincentLiu what are the different ways...?

                                        Naveen_D

                                        1 Reply Last reply
                                        0
                                        • Naveen_DN Offline
                                          Naveen_DN Offline
                                          Naveen_D
                                          wrote on last edited by
                                          #21

                                          Hello, can anyone please help me out with this...
                                          thanks

                                          Naveen_D

                                          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