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. Connect QML Signal with C++ Slot
Forum Updated to NodeBB v4.3 + New Features

Connect QML Signal with C++ Slot

Scheduled Pinned Locked Moved Solved QML and Qt Quick
8 Posts 3 Posters 20.5k 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.
  • beeckscheB Offline
    beeckscheB Offline
    beecksche
    wrote on last edited by beecksche
    #1

    Hey,
    i'm new to QML and want to connect a signal from QML to my C++ class. I have read the tutorials but it doesn't work :(
    Here are my files:

    main.qml

    ApplicationWindow {
        id: window
        visible: true
        width : 640
        height: 480
    
        title: qsTr("Test")
    
        header: ToolBar {
            Material.foreground: "white"
    
            RowLayout {
                spacing: 20
                 anchors.fill: parent
    
                  ToolButton {
                      contentItem: Image {
                          fillMode: Image.Pad
                          horizontalAlignment: Image.AlignHCenter
                          verticalAlignment: Image.AlignVCenter
                          source: "qrc:/images/drawer.png"
                      }
                      onClicked: drawer.open()
                  }
    
                 Label {
                     id: titleLabel
                     text: "Test"
                     font.pixelSize: 20
                     elide: Label.ElideRight
                     horizontalAlignment: Qt.AlignHCenter
                     verticalAlignment: Qt.AlignVCenter
                     Layout.fillWidth: true
                 }
             }
         }
    
        Drawer {
            id: drawer
    	objectName: "drawer"
            width: Math.min(window.width, window.height) / 4
            height: window.height
    
            ListView {
                id: listView
                currentIndex: -1
                anchors.fill: parent
    
    
                delegate: ItemDelegate {
                    width: parent.width
                    height: 100
    
                    Item {
                        width: parent.width
                        height: parent.height
                        RowLayout {
                            id: layout
                            spacing: 20
                            anchors.fill: parent
    
                            Image {
                                Layout.preferredHeight: 50
                                Layout.preferredWidth: 50
                                Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
    
                                source: model.imagePath
                            }
    
                            Text {
                                text: model.title
                            }
                        }
                    }
    
                    highlighted: ListView.isCurrentItem
                    onClicked: {
                        if (listView.currentIndex != index) {
                            listView.currentIndex = index
                            titleLabel.text = model.title
                            stackView.replace(model.source)
                        }
                        drawer.close()
                    }
    
    
                }
    
                model: ListModel {
                ListElement{title: "Home"; source: "qrc:/Home.qml"; imagePath: "qrc:/images/home.png"; }
    
                }
    
                ScrollIndicator.vertical: ScrollIndicator { }
            }
        }
    
        StackView {
            id: stackView
    	objectName: "stackView"
            anchors.fill: parent
        }
    }
    

    Home.qml

    import QtQuick 2.6
    import QtQuick.Controls 2.0
    
    Pane {
        id: homePane
    
        signal qmlSignal()
    
        Column {
            anchors.fill: parent
    
            ToolButton {
    	    id: myButton
                anchors.horizontalCenter: parent.horizontalCenter
                anchors.verticalCenter:  parent.verticalCenter
                text: "Click Me"
    
                onClicked:
                {
                    console.log("clicked")
                    homePane.qmlSignal()
                }
    
            }
        }
    }
    

    main.cpp

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QQuickStyle>
    #include <QDebug>
    
    class MyClass : public QObject
    {
    	Q_OBJECT
    public:
    	MyClass(QObject *parent = 0) : QObject(parent) {}
    	~MyClass() {}
    public slots:
    	void clicked()  {
             qDebug() << "Slot";
    	}
    
    };
    
    #include "main.moc"
    
    int main(int argc, char *argv[])
    {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
        QGuiApplication app(argc, argv);
    
        QQuickStyle::setStyle("Default");
    
        QQmlApplicationEngine engine;
        engine.load(QUrl(QLatin1String("qrc:/main.qml")));
    	
        QQmlApplicationEngine engine2;
        engine2.load(QUrl(QLatin1String("qrc:/Home.qml")));
    
        QObject *homePane = engine2.rootObjects().first();
    
        MyClass *slot = new MyClass();
    
        qDebug() << QObject::connect(homePane, SIGNAL(qmlSignal()), slot, SLOT(clicked()));
    
        return app.exec();
    }
    

    The QObject::connect function returns true.

    But when i click my button the slot will not be invoked!

    Thanks for help!

    1 Reply Last reply
    0
    • p3c0P Offline
      p3c0P Offline
      p3c0
      Moderators
      wrote on last edited by
      #2

      @beecksche That is because the button you click is under QQmlApplicationEngine engine context while you have connected to a signal from a QML file under context of QQmlApplicationEngine engine2 .
      There is no need for the second one.

      157

      1 Reply Last reply
      1
      • beeckscheB Offline
        beeckscheB Offline
        beecksche
        wrote on last edited by beecksche
        #3

        @p3c0 Thanks for the quick reply.
        But how can i acces the homePane from the engine?

        p3c0P 1 Reply Last reply
        0
        • ? Offline
          ? Offline
          A Former User
          wrote on last edited by
          #4

          Hi! Here is a small example how to do it similar to how you already tried it. I will also write another posting with what I think is better practice.

          stuff.h

          #ifndef STUFF_H
          #define STUFF_H
          
          #include <QObject>
          
          class Stuff : public QObject
          {
              Q_OBJECT
          public:
              explicit Stuff(QObject *parent = 0);
          
          public slots:
              void onClicked();
          };
          
          #endif // STUFF_H
          

          stuff.cpp

          #include "stuff.h"
          
          #include <QDebug>
          
          Stuff::Stuff(QObject *parent) : QObject(parent)
          {
          }
          
          void Stuff::onClicked()
          {
              qDebug() << "clicked";
          }
          

          main.cpp

          #include <QGuiApplication>
          #include <QQmlApplicationEngine>
          #include <QQmlContext>
          
          #include "stuff.h"
          
          int main(int argc, char *argv[])
          {
              QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
              QGuiApplication app(argc, argv);
          
              Stuff stuff;
          
              QQmlApplicationEngine engine;
              engine.load(QUrl(QLatin1String("qrc:/main.qml")));
          
              QObject* home = engine.rootObjects().first()->findChild<QObject*>("MyHomeObject");
              QObject::connect(home, SIGNAL(clicked()), &stuff, SLOT(onClicked()));
          
              return app.exec();
          }
          

          main.qml

          import QtQuick 2.7
          import QtQuick.Controls 2.0
          import QtQuick.Layouts 1.0
          
          ApplicationWindow {
              visible: true
              width: 640
              height: 480
              title: qsTr("Hello World")
          
              Home {
                  objectName: "MyHomeObject"
              }
          }
          

          Home.qml

          import QtQuick 2.7
          import QtQuick.Controls 2.0
          
          Rectangle {
              id: rect
              width: 100
              height: 100
              color: "orange"
          
              signal clicked()
          
              Button {
                  anchors.centerIn: parent
                  text: "Click me"
                  onClicked: rect.clicked()
              }
          }
          
          1 Reply Last reply
          3
          • beeckscheB beecksche

            @p3c0 Thanks for the quick reply.
            But how can i acces the homePane from the engine?

            p3c0P Offline
            p3c0P Offline
            p3c0
            Moderators
            wrote on last edited by
            #5

            @beecksche said in Connect QML Signal with C++ Slot:

            @p3c0 Thanks for the quick reply.
            But how can i acces the homePane from the engine?

            In the similar manner you need to get access to Home object.

            157

            1 Reply Last reply
            0
            • ? Offline
              ? Offline
              A Former User
              wrote on last edited by
              #6

              So, now what I think is better: You create one single object ("backend") that acts as the C++ interface to your business logic. The QtQuick GUI will only interact with the C++ part through that object.

              backend.h

              #ifndef BACKEND_H
              #define BACKEND_H
              
              #include <QObject>
              
              class Backend : public QObject
              {
                  Q_OBJECT
              public:
                  explicit Backend(QObject *parent = 0);
              
              public slots:
                  void doSomething();
              };
              
              #endif // BACKEND_H
              

              backend.cpp

              #include "backend.h"
              
              #include <QDebug>
              
              Backend::Backend(QObject *parent) : QObject(parent)
              {
              }
              
              void Backend::doSomething()
              {
                  qDebug() << "Do something";
              }
              

              main.cpp

              #include <QGuiApplication>
              #include <QQmlApplicationEngine>
              #include <QQmlContext>
              
              #include "backend.h"
              
              int main(int argc, char *argv[])
              {
                  QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
                  QGuiApplication app(argc, argv);
              
                  QQmlApplicationEngine engine;
                  Backend backend;
                  engine.rootContext()->setContextProperty("backend", &backend);
                  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
              
              ApplicationWindow {
                  visible: true
                  width: 640
                  height: 480
                  title: qsTr("Hello World")
              
                 Home {}
              }
              

              Home.qml

              import QtQuick 2.7
              import QtQuick.Controls 2.0
              
              Rectangle {
                  width: 100
                  height: 100
                  Button {
                      anchors.centerIn: parent
                      text: "Click me"
                      onClicked: backend.doSomething()
                  }
              }
              
              1 Reply Last reply
              5
              • beeckscheB Offline
                beeckscheB Offline
                beecksche
                wrote on last edited by beecksche
                #7

                Wow, thanks a lot for the answers! That's amazing!
                I'll try the solutions as soon as possible!

                Edit1:
                @Wieland The backend mechanism is really nice! Is there a way to connect the signals from the backend to qml functions?

                Edit2:
                Sometimes i should first search by myself ... I found the the answer:
                http://doc.qt.io/qt-5/qtqml-cppintegration-contextproperties.html

                Thanks for the help !

                ? 1 Reply Last reply
                0
                • beeckscheB beecksche

                  Wow, thanks a lot for the answers! That's amazing!
                  I'll try the solutions as soon as possible!

                  Edit1:
                  @Wieland The backend mechanism is really nice! Is there a way to connect the signals from the backend to qml functions?

                  Edit2:
                  Sometimes i should first search by myself ... I found the the answer:
                  http://doc.qt.io/qt-5/qtqml-cppintegration-contextproperties.html

                  Thanks for the help !

                  ? Offline
                  ? Offline
                  A Former User
                  wrote on last edited by
                  #8

                  @beecksche Great that you already solved it :-) But if you should encounter any further problems then don't hesitate to just ask again.

                  1 Reply Last reply
                  0
                  • B Bob64 referenced this topic on

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved