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.