Signals and Slots in Qt QML

And we got to transfer data between a layer of QML and C ++ layer. Frankly speaking, the principle is as simple as just using signals and slots in a single layer C ++. Especially in Qt 5.5.

  • appcore.h – application core file header;

  • appcore.cpp – application core source file.

And we continue to work and be with QQMLApplicationEngine. You will need to just take from the engine QML context and download it to a new class of object from which the signals in which data will be transmitted will be received.

appcore.h

Our class header file is as simple as a penny. In it there is a one meter (variable of type int), a slot that will increase the counter by one and run signal, which is also one in the class and which will transmit the counter value in QML-interface.

#ifndef APPCORE\_H
#define APPCORE\_H
 
#include <QObject>
 
class AppCore : public QObject
{
    Q\_OBJECT
public:
    explicit AppCore(QObject *parent = 0);
 
signals:
    // Signal to transmit data to interface qml-interface
    void sendToQml(int count);
 
public slots:
    // The slot for the receiving of data from the QML-interface
    void receiveFromQml();
 
private:
    int count;  // Counter
};
 
#endif // APPCORE\_H

appcore.cpp

#include "appcore.h"
 
AppCore::AppCore(QObject *parent) : QObject(parent)
{
    count = 0;
}
 
void AppCore::receiveFromQml()
{
    count++;
    emit sendToQml(count);
}

main.cpp

And here we have connected to our class interface written in QML.

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "appcore.h"
 
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
 
    QQmlApplicationEngine engine; 
 
    AppCore appCore;    
    QQmlContext *context = engine.rootContext();   
    /* Load the object in context to establish a connection,
     * also define the name by which the connection will be
     * */
    context->setContextProperty("appCore", &appCore);
 
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
 
    return app.exec();
}

main.qml

Here is part of the code, so as not to distract you from the main. Namely, a compound layer in QML Connections by means of the object as a target is set your class is indicated in the context. Treatment is carried out on the text name that is loaded into the QML engine context, together with the object itself.

To receive signals from the C ++ layer is necessary in the Connections register a function that will be called in much the same way as the target signal, but will start on a signal and then the name with a capital letter. That is, the following logic

  • signalToQml – on C++

  • onSignalToQml – on QML

But the call Slot will be somewhat different. For example, we have a class object in C ++, to which we refer by name appCore (declared aim in Connections). And then we call the slot. That is as follows: appCore.slotSomething (count).

Call slot in this code is done by pressing the OK button in the dialog, and in Cancel the call does not occur. At the same time, appCore object in C ++ code, the counter increases by one and causes the signal to put counter value in a text label applications.

import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Dialogs 1.2
 
ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World") 
    color: "white"
 
    /* With Connections object
     * Set up a connection to the core application class
     * */
    Connections {
        target: appCore // Specify the target connection
        /* We declare and implement a function as an object parameter and 
         * first name similar to the name of the signal. 
         * The difference is that we add at the beginning on and 
         * then write with a capital letter
         * */
        onSendToQml: {
            labelCount.text = count // Set the counter to a text label
        }
    }
 
    MainForm {
        // Stretch the object of the main window over the parent element
        anchors.fill: parent
 
        // Create text label
        Text {
            id: labelCount
            anchors.left: parent.left
            anchors.right: parent.right
            anchors.top: parent.top
            height: 300
            verticalAlignment: Text.AlignVCenter
            horizontalAlignment: Text.AlignHCenter
            text: "Hello, World !!!"
        }
 
        button1.style: ButtonStyle {
            // The code from the previous lesson
        }
 
        button2.style: ButtonStyle {
            // The code from the previous lesson
        }
 
        // Start a dialogue by pressing any of the buttons in the main window
        button1.onClicked: dialogAndroid.open();
        button2.onClicked: dialogAndroid.open();
 
        Dialog {
            id: dialogAndroid
            width: 600  // set the width of the dialog works on the desktop, but it does not work on Android
            height: 500 // set the height of the dialog works on the desktop, but it does not work on Android
 
            contentItem: Rectangle {
                width: 600          // Set the width, necessary for Android-devices
                height: 500         // Set the width, necessary for Android-devices
                color: "#f7f7f7"    // 
 
                // The area for the dialog box message
                Rectangle {
                    // The code from the previous lesson
                }
 
                Rectangle {
                    id: dividerHorizontal
                    // The code from the previous lesson
                }
 
                Row {
                    id: row
                    // The code from the previous lesson
 
                    Button {
                        id: dialogButtonCancel
 
                        // The code from the previous lesson
                        onClicked: dialogAndroid.close()
                    }
 
                    Rectangle {
                        id: dividerVertical
                        // The code from the previous lesson
                    }
 
                    Button {
                        id: dialogButtonOk
 
                        // The code from the previous lesson
 
                        onClicked: {
                            /* Before you close the dialog by clicking on OK,
                             * Send the data in the slot application core
                             * */
                            appCore.receiveFromQml()
                            // And then close the dialogue
                            dialogAndroid.close()
                        }
                    }
                }
            }
        }
    }
}

Result

The result is a simple interaction between the C ++ and QML based on all of the same signals and slots. But the result of the application you can see in the video tutorial.

Last updated