Book Image

QT5 Blueprints

By : Symeon Huang
Book Image

QT5 Blueprints

By: Symeon Huang

Overview of this book

Table of Contents (17 chapters)
Qt 5 Blueprints
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

Connecting C++ slots to QML signals


The separation of the user interface and backend allows us to connect C++ slots to the QML signals. Although it's possible to write processing functions in QML and manipulate interface items in C++, it violates the principle of the separation. Therefore, you may want to know how to connect a C++ slot to a QML signal at first. As for connecting a QML slot to a C++ signal, I'll introduce that later in this book.

In order to demonstrate this, we need to create a C++ class in the first place by right-clicking on the project in the Projects panel and selecting Add New…. Then, click on C++ Class in the pop-up window. The newly created class should at least inherit from QObject by choosing QObject as its base class. This is because a plain C++ class can't include Qt's slots or signals. The header file's content is displayed as follows:

#ifndef PROCESSOR_H
#define PROCESSOR_H

#include <QObject>

class Processor : public QObject
{
    Q_OBJECT
public:
    explicit Processor(QObject *parent = 0);

public slots:
    void onMenuClicked(const QString &);
};

#endif // PROCESSOR_H

Here's the content of the source file:

#include <QDebug>
#include "processor.h"

Processor::Processor(QObject *parent) :
    QObject(parent)
{
}

void Processor::onMenuClicked(const QString &str)
{
    qDebug() << str;
}

The C++ file is the same as the one we dealt with in the previous topics. The onMenuClicked slot I defined is simply to output the string that passes through the signal. Note that you have to include QDebug if you want to use the built-in functions of qDebug, qWarning, qCritical, and so on.

The slot is prepared, so we need to add a signal to the QML file. The QML file is changed to the following code:

import QtQuick 2.3
import QtQuick.Controls 1.2

ApplicationWindow {
    id: window
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello QML")
    signal menuClicked(string str)

    menuBar: MenuBar {
        Menu {
            title: qsTr("File")
            MenuItem {
                text: qsTr("Exit")
                shortcut: "Ctrl+Q"
                onTriggered: Qt.quit()
            }
            MenuItem {
                text: qsTr("Click Me")
                onTriggered: window.menuClicked(text)
            }
        }
    }

    Text {
        id: hw
        text: qsTr("Hello World")
        font.capitalization: Font.AllUppercase
        anchors.centerIn: parent
    }

    Label {
        anchors { bottom: hw.top; bottomMargin: 5; horizontalCenter: hw.horizontalCenter }
        text: qsTr("Hello Qt Quick")
    }
}

As you can see, I specified the ID of the root ApplicationWindow item to window and declared a signal named menuClicked. In addition to this, there is another MenuItem in the menu file. It emits the menuClicked signal of window, using its text as the parameter.

Now, let's connect the slot in the C++ file to this newly created QML signal. Edit the main.cpp file.

#include <QApplication>
#include <QQmlApplicationEngine>
#include "processor.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:///main.qml")));

    QObject *firstRootItem = engine.rootObjects().first();
    Processor myProcessor;
    QObject::connect(firstRootItem, SIGNAL(menuClicked(QString)), &myProcessor, SLOT(onMenuClicked(QString)));

    return app.exec();
}

The item in the QML file is accessed as QObject in C++ and it could be cast to QQuickItem. For now, we only need to connect its signal, so QObject will do.

You may notice that I used the old-style syntax of the connect statement. This is because QML is dynamic and the C++ compiler can't detect the existence of the signal in the QML file. Since things in QML are checked at runtime, it doesn't make sense to use the old syntax here.

When you run this application and navigate to File | Click Me in the menu bar, you'll see Application Output in Qt Creator:

"Click Me"

Let's review this process again. Triggering the Click Me menu item resulted in the emission of the window's signal menuClicked. This signal passed the text of MenuItem, which is Click Me, to the slot in C++ class Processor, and the processor myProcessor slot onMenuClicked printed the string to the Application Output panel.