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. Connecting C++ signal to QML slot
Forum Updated to NodeBB v4.3 + New Features

Connecting C++ signal to QML slot

Scheduled Pinned Locked Moved Solved QML and Qt Quick
10 Posts 5 Posters 1.3k 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.
  • M Offline
    M Offline
    Mary_M
    wrote on last edited by
    #1

    Hi,
    I am new to qt and want to pass a simple signal from a c++ widget to qml. I followed the structure in this document with a few changes. . The code complies but nothing shows up due to this error:
    QObject::connect: No such slot QQuickItem::qmlSlot(QVariant) in ../qmltest/mainwindow.cpp:15
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    qmltest.pro:

    QT += core gui qml quickwidgets
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    CONFIG += c++11
    ...

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    mainwindow.cpp:
    MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    {
    auto cppObj = new Widget();
    auto quickWidget = new QQuickWidget(QUrl("qrc:/main.qml"));
    auto qmlObj = quickWidget->rootObject();

    // Connect C++ signal to QML slot
    connect(cppObj, SIGNAL(cppSignal(QVariant)),
            qmlObj, SLOT(qmlSlot(QVariant)));
    

    }
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    mainwindow.h:
    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    };
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    widget.cpp:

    Widget::Widget(QWidget *parent)
    : QWidget(parent)
    {

    button = new QPushButton("Click Me!", this);
    connect(button, &QPushButton::clicked, [=] {
        emit cppSignal("hello");
    });
    

    }
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    widget.h:

    class Widget : public QWidget
    {
    Q_OBJECT
    QPushButton *button;
    signals:
    void cppSignal(const QVariant& sentMsg) const;

    public:
    Widget(QWidget *parent = 0);
    ~Widget();
    };
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    main.qml:
    import QtQuick 2.15
    import QtQuick.Controls 2.15

    Item {
    Rectangle {
    width: 100; height: 100
    function qmlSlot(receivedMsg) {
    console.log("QML received: " + receivedMsg)
    }

    }
    

    }

    Can anyone help me with this? I also used MetaObject::invokeMethod(qmlObj, "qmlSlot"); same error.
    Note that in this project I designed a keyboard by QWidgets to type and want to pass the pushed keys to the qml which is a chat GUI in this work. So I have to use qquickwidgets to show both keyboard and chat GUI in the same window.

    raven-worxR eyllanescE 2 Replies Last reply
    0
    • M Mary_M

      Hi,
      I am new to qt and want to pass a simple signal from a c++ widget to qml. I followed the structure in this document with a few changes. . The code complies but nothing shows up due to this error:
      QObject::connect: No such slot QQuickItem::qmlSlot(QVariant) in ../qmltest/mainwindow.cpp:15
      ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

      qmltest.pro:

      QT += core gui qml quickwidgets
      greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
      CONFIG += c++11
      ...

      ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

      mainwindow.cpp:
      MainWindow::MainWindow(QWidget *parent)
      : QMainWindow(parent)
      {
      auto cppObj = new Widget();
      auto quickWidget = new QQuickWidget(QUrl("qrc:/main.qml"));
      auto qmlObj = quickWidget->rootObject();

      // Connect C++ signal to QML slot
      connect(cppObj, SIGNAL(cppSignal(QVariant)),
              qmlObj, SLOT(qmlSlot(QVariant)));
      

      }
      ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      mainwindow.h:
      class MainWindow : public QMainWindow
      {
      Q_OBJECT

      public:
      MainWindow(QWidget *parent = nullptr);
      ~MainWindow();
      };
      ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      widget.cpp:

      Widget::Widget(QWidget *parent)
      : QWidget(parent)
      {

      button = new QPushButton("Click Me!", this);
      connect(button, &QPushButton::clicked, [=] {
          emit cppSignal("hello");
      });
      

      }
      ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      widget.h:

      class Widget : public QWidget
      {
      Q_OBJECT
      QPushButton *button;
      signals:
      void cppSignal(const QVariant& sentMsg) const;

      public:
      Widget(QWidget *parent = 0);
      ~Widget();
      };
      ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      main.qml:
      import QtQuick 2.15
      import QtQuick.Controls 2.15

      Item {
      Rectangle {
      width: 100; height: 100
      function qmlSlot(receivedMsg) {
      console.log("QML received: " + receivedMsg)
      }

      }
      

      }

      Can anyone help me with this? I also used MetaObject::invokeMethod(qmlObj, "qmlSlot"); same error.
      Note that in this project I designed a keyboard by QWidgets to type and want to pass the pushed keys to the qml which is a chat GUI in this work. So I have to use qquickwidgets to show both keyboard and chat GUI in the same window.

      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by raven-worx
      #2

      @Mary_M
      you try to connect to a method of the rootItem(). But in your qml file the object with the desired method is not the root item. It has a parent Item.

      Its probably anyway easier to do the connection inside QML and not in C++.

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      M 1 Reply Last reply
      0
      • raven-worxR raven-worx

        @Mary_M
        you try to connect to a method of the rootItem(). But in your qml file the object with the desired method is not the root item. It has a parent Item.

        Its probably anyway easier to do the connection inside QML and not in C++.

        M Offline
        M Offline
        Mary_M
        wrote on last edited by
        #3

        @raven-worx Thank you! I tried with the root item, no error but the text doesn't show up! Also, I need the signal to be emitted from C++.

        1 Reply Last reply
        0
        • M Mary_M

          Hi,
          I am new to qt and want to pass a simple signal from a c++ widget to qml. I followed the structure in this document with a few changes. . The code complies but nothing shows up due to this error:
          QObject::connect: No such slot QQuickItem::qmlSlot(QVariant) in ../qmltest/mainwindow.cpp:15
          ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

          qmltest.pro:

          QT += core gui qml quickwidgets
          greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
          CONFIG += c++11
          ...

          ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

          mainwindow.cpp:
          MainWindow::MainWindow(QWidget *parent)
          : QMainWindow(parent)
          {
          auto cppObj = new Widget();
          auto quickWidget = new QQuickWidget(QUrl("qrc:/main.qml"));
          auto qmlObj = quickWidget->rootObject();

          // Connect C++ signal to QML slot
          connect(cppObj, SIGNAL(cppSignal(QVariant)),
                  qmlObj, SLOT(qmlSlot(QVariant)));
          

          }
          ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
          mainwindow.h:
          class MainWindow : public QMainWindow
          {
          Q_OBJECT

          public:
          MainWindow(QWidget *parent = nullptr);
          ~MainWindow();
          };
          ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
          widget.cpp:

          Widget::Widget(QWidget *parent)
          : QWidget(parent)
          {

          button = new QPushButton("Click Me!", this);
          connect(button, &QPushButton::clicked, [=] {
              emit cppSignal("hello");
          });
          

          }
          ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
          widget.h:

          class Widget : public QWidget
          {
          Q_OBJECT
          QPushButton *button;
          signals:
          void cppSignal(const QVariant& sentMsg) const;

          public:
          Widget(QWidget *parent = 0);
          ~Widget();
          };
          ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
          main.qml:
          import QtQuick 2.15
          import QtQuick.Controls 2.15

          Item {
          Rectangle {
          width: 100; height: 100
          function qmlSlot(receivedMsg) {
          console.log("QML received: " + receivedMsg)
          }

          }
          

          }

          Can anyone help me with this? I also used MetaObject::invokeMethod(qmlObj, "qmlSlot"); same error.
          Note that in this project I designed a keyboard by QWidgets to type and want to pass the pushed keys to the qml which is a chat GUI in this work. So I have to use qquickwidgets to show both keyboard and chat GUI in the same window.

          eyllanescE Offline
          eyllanescE Offline
          eyllanesc
          wrote on last edited by eyllanesc
          #4

          @Mary_M It is recommended to make the connection in qml:

          *.cpp

          auto cppObj = new Widget();
          auto quickWidget = new QQuickWidget();
          quickWidget->rootContext()->setContextProperty("cppObj", cppObj);
          quickWidget->setSource(QUrl("qrc:/main.qml"));
          

          main.qml

          import QtQuick 2.15
          import QtQuick.Controls 2.15
          
          Item {
              Rectangle {
                  width: 100; height: 100
              }
              Connections{
                  target: cppObj
                  function onCppSignal(receivedMsg){
                      console.log("QML received: " + receivedMsg)
                  }
              }
          }
          

          If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

          M 1 Reply Last reply
          0
          • GabrielRRG Offline
            GabrielRRG Offline
            GabrielRR
            wrote on last edited by GabrielRR
            #5

            Try something like this:

            Q_INVOKABLE void triggerEvent(QString text) {
             emit signalEvent(text);
            }
            Person() {
             startTimer(1000);
            }
            void timerEvent(QTimerEvent *e) {
             QString text = "Hello";
             triggerEvent(text);
            }
            
            signals: 
            void signalEvent(QString text);
            
            //In qml:
            
            id: myQmlObject
            onSignalEvent: {
             console.log(" Message " + text);
            }
            

            Lic-Ing. Jose Gabriel Lopez Villalobos
            Embedded Software Engineer
            RidgeRun Engineering Ltd.
            www.ridgerun.com
            Email: gabriel.lopez@ridgerun.com

            M 1 Reply Last reply
            0
            • eyllanescE eyllanesc

              @Mary_M It is recommended to make the connection in qml:

              *.cpp

              auto cppObj = new Widget();
              auto quickWidget = new QQuickWidget();
              quickWidget->rootContext()->setContextProperty("cppObj", cppObj);
              quickWidget->setSource(QUrl("qrc:/main.qml"));
              

              main.qml

              import QtQuick 2.15
              import QtQuick.Controls 2.15
              
              Item {
                  Rectangle {
                      width: 100; height: 100
                  }
                  Connections{
                      target: cppObj
                      function onCppSignal(receivedMsg){
                          console.log("QML received: " + receivedMsg)
                      }
                  }
              }
              
              M Offline
              M Offline
              Mary_M
              wrote on last edited by
              #6

              @eyllanesc Thank you so much! but when I use connections this is the error:
              QObject::connect: Cannot connect Widget::cppSignal(QVariant) to (nullptr)::qmlSlot(QVariant)

              I also tried this one but still the same:
              Item {
              Rectangle {
              id: rect
              width: 100; height: 100
              Text{id:myText} }
              Connections{
              target: cppObj
              function onCppSignal(receivedMsg){
              MyText.text = receivedMsg;
              }
              }
              }

              eyllanescE 1 Reply Last reply
              0
              • GabrielRRG GabrielRR

                Try something like this:

                Q_INVOKABLE void triggerEvent(QString text) {
                 emit signalEvent(text);
                }
                Person() {
                 startTimer(1000);
                }
                void timerEvent(QTimerEvent *e) {
                 QString text = "Hello";
                 triggerEvent(text);
                }
                
                signals: 
                void signalEvent(QString text);
                
                //In qml:
                
                id: myQmlObject
                onSignalEvent: {
                 console.log(" Message " + text);
                }
                
                M Offline
                M Offline
                Mary_M
                wrote on last edited by
                #7

                @GabrielRR Thanks! but how can I use this in widget.cpp not in mainwindow?

                1 Reply Last reply
                0
                • M Mary_M

                  @eyllanesc Thank you so much! but when I use connections this is the error:
                  QObject::connect: Cannot connect Widget::cppSignal(QVariant) to (nullptr)::qmlSlot(QVariant)

                  I also tried this one but still the same:
                  Item {
                  Rectangle {
                  id: rect
                  width: 100; height: 100
                  Text{id:myText} }
                  Connections{
                  target: cppObj
                  function onCppSignal(receivedMsg){
                  MyText.text = receivedMsg;
                  }
                  }
                  }

                  eyllanescE Offline
                  eyllanescE Offline
                  eyllanesc
                  wrote on last edited by
                  #8

                  @Mary_M Have you deleted your C++ connection attempt? That error message is not from QML but from C++, also remove build folder and compile.

                  If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

                  M 1 Reply Last reply
                  0
                  • eyllanescE eyllanesc

                    @Mary_M Have you deleted your C++ connection attempt? That error message is not from QML but from C++, also remove build folder and compile.

                    M Offline
                    M Offline
                    Mary_M
                    wrote on last edited by Mary_M
                    #9

                    @eyllanesc You are right! I deleted connect in mainwindow now and built it again. No error now but no output either! Only empty window showed up. At the end I used Qframe and gridline to add button and rect alongside. Many thanks!

                    Pablo J. RoginaP 1 Reply Last reply
                    0
                    • M Mary_M

                      @eyllanesc You are right! I deleted connect in mainwindow now and built it again. No error now but no output either! Only empty window showed up. At the end I used Qframe and gridline to add button and rect alongside. Many thanks!

                      Pablo J. RoginaP Offline
                      Pablo J. RoginaP Offline
                      Pablo J. Rogina
                      wrote on last edited by
                      #10

                      @Mary_M If your issue is solved please don't forget to mark the post as such!

                      Upvote the answer(s) that helped you solve the issue
                      Use "Topic Tools" button to mark your post as Solved
                      Add screenshots via postimage.org
                      Don't ask support requests via chat/PM. Please use the forum so others can benefit from the solution in the future

                      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