Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
QT5 Blueprints
QT5 Blueprints

QT5 Blueprints: Design, build, and deploy cross-platform GUI projects using the amazingly powerful Qt 5 framework

eBook
€32.99
Paperback
€41.99
Subscription
Free Trial
Renews at €18.99p/m

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Table of content icon View table of contents Preview book icon Preview Book

QT5 Blueprints

Chapter 1. Creating Your First Qt Application

GUI programming is not as difficult as you think. At least it's not when you come to the world of Qt. This book will take you through this world and give you an insight into this incredibly amazing toolkit. It doesn't matter whether you've heard of it or not, as long as you have essential knowledge of C++ programming.

In this chapter, we will get you comfortable with the development of Qt applications. Simple applications are used as a demonstration for you to cover the following topics:

  • Creating a new project
  • Changing the layout of widgets
  • Understanding the mechanism of signals and slots
  • Connecting two signals
  • Creating a Qt Quick application
  • Connecting C++ slots to QML signals

Creating a new project

If you haven't installed Qt 5, refer to http://www.qt.io/download to install the latest version of it. It's recommended that you install the Community version, which is totally free and compliant with GPL/LGPL. Typically, the installer will install both Qt Library and Qt Creator for you. In this book, we will use Qt 5.4.0 and Qt Creator 3.3.0. Later versions may have slight differences but the concept remains the same. It's highly recommended that you install Qt Creator if you don't have it on your computer, because all the tutorials in this book are based on it. It is also the official IDE for the development of Qt applications. Although you may be able to develop Qt applications with other IDEs, it tends to be much more complex. So if you're ready, let's go for it by performing the following steps:

  1. Open Qt Creator.
  2. Navigate to File | New File or Project.
  3. Select Qt Widgets Application.
  4. Enter the project's name and location. In this case, the project's name is layout_demo.

You may wish to follow the wizard and keep the default values. After this process, Qt Creator will generate the skeleton of the project based on your choices. The UI files are under the Forms directory. When you double-click on a UI file, Qt Creator will redirect you to the integrated designer. The mode selector should have Design highlighted, and the main window should contain several sub-windows to let you design the user interface. This is exactly what we are going to do. For more details about Qt Creator UI, refer to http://doc.qt.io/qtcreator/creator-quick-tour.html.

Drag three push buttons from the widget box (widget palette) into the frame of MainWindow in the center. The default text displayed on these buttons is PushButton, but you can change the text if you want by double-clicking on the button. In this case, I changed the buttons to Hello, Hola, and Bonjour, accordingly. Note that this operation won't affect the objectName property. In order to keep it neat and easy to find, we need to change the objectName property. The right-hand side of the UI contains two windows. The upper-right section includes Object Inspector and the lower-right side includes Property Editor. Just select a push button; you can easily change objectName in Property Editor. For the sake of convenience, I changed these buttons' objectName properties to helloButton, holaButton, and bonjourButton respectively.

Tip

It's a good habit to use lowercase for the first letter of objectName and an uppercase letter for Class name. This helps your code to be more readable by people who are familiar with this convention.

Okay, it's time to see what you have done to the user interface of your first Qt application. Click on Run on the left-hand side panel. It will build the project automatically and then run it. It's amazing to see that the application has the exact same interface as the design, isn't it? If everything is alright, the application should appear similar to what is shown in the following screenshot:

Creating a new project

You may want to look at the source code and see what happened there. So, let's go back to the source code by returning to the Edit mode. Click on the Edit button in the mode selector. Then, double-click on main.cpp in the Sources folder of the Projects tree view. The code for main.cpp is shown as follows:

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

Note

The QApplication class manages the GUI application's control flow and the main settings.

Actually, you don't need to and you probably won't change too much in this file. The first line of the main scope just initializes the applications on a user's desktop and handles some events. Then there is also an object, w, which belongs to the MainWindow class. As for the last line, it ensures that the application won't terminate after execution but will keep in an event loop, so that it is able to respond to external events such as mouse clicks and window state changes.

Last but not least, let's see what happens during the initialization of the MainWindow object, w. It is the content of mainwindow.h, shown as follows:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

You may feel a bit surprised seeing a Q_OBJECT macro if this is your first time writing a Qt application. In the QObject documentation, it says:

The Q_OBJECT macro must appear in the private section of a class definition that declares its own signals and slots or that uses other services provided by Qt's meta-object system.

Well, this means that QObject has to be declared if you're going to use Qt's meta-object system and (or) its signals and slots mechanism. The signals and slots, which are almost the core of Qt, will be included later in this chapter.

There is a private member named ui, which is a pointer of the MainWindow class of the Ui namespace. Do you remember the UI file we edited before? What the magic of Qt does is that it links the UI file and the parental source code. We can manipulate the UI through code lines as well as design it in Qt Creator's integrated designer. Finally, let's look into the construction function of MainWindow in mainwindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

Did you see where the user interface comes from? It's the member setupUi function of Ui::MainWindow that initializes it and sets it up for us. You may want to check what happens if we change the member function to something like this:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->holaButton->setEnabled(false);
}

What happened here? The Hola button can't be clicked on because we disabled it! It has the same effect if the enabled box is unchecked in the designer instead of writing a statement here. Please apply this change before heading to the next topic, because we don't need a disabled push button to do any demonstrations in this chapter.

Changing the layout of widgets

You already know how to add and move widgets in the Design mode. Now, we need to make the UI neat and tidy. I'll show you how to do this step by step.

A quick way to delete a widget is to select it and press the Delete button. Meanwhile, some widgets, such as the menu bar, status bar, and toolbar can't be selected, so we have to right-click on them in Object Inspector and delete them. Since they are useless in this example, it's safe to remove them and we can do this for good.

Okay, let's understand what needs to be done after the removal. You may want to keep all these push buttons on the same horizontal axis. To do this, perform the following steps:

  1. Select all the push buttons either by clicking on them one by one while keeping the Ctrl key pressed or just drawing an enclosing rectangle containing all the buttons.
  2. Right-click and select Layout | LayOut Horizontally, The keyboard shortcut for this is Ctrl + H.
  3. Resize the horizontal layout and adjust its layoutSpacing by selecting it and dragging any of the points around the selection box until it fits best.

Hmm…! You may have noticed that the text of the Bonjour button is longer than the other two buttons, and it should be wider than the others. How do you do this? You can change the property of the horizontal layout object's layoutStretch property in Property Editor. This value indicates the stretch factors of the widgets inside the horizontal layout. They would be laid out in proportion. Change it to 3,3,4, and there you are. The stretched size definitely won't be smaller than the minimum size hint. This is how the zero factor works when there is a nonzero natural number, which means that you need to keep the minimum size instead of getting an error with a zero divisor.

Now, drag Plain Text Edit just below, and not inside, the horizontal layout. Obviously, it would be neater if we could extend the plain text edit's width. However, we don't have to do this manually. In fact, we could change the layout of the parent, MainWindow. That's it! Right-click on MainWindow, and then navigate to Lay out | Lay Out Vertically. Wow! All the children widgets are automatically extended to the inner boundary of MainWindow; they are kept in a vertical order. You'll also find Layout settings in the centralWidget property, which is exactly the same thing as the previous horizontal layout.

The last thing to make this application halfway decent is to change the title of the window. MainWindow is not the title you want, right? Click on MainWindow in the object tree. Then, scroll down its properties to find windowTitle. Name it whatever you want. In this example, I changed it to Greeting. Now, run the application again and you will see it looks like what is shown in the following screenshot:

Changing the layout of widgets

Understanding the mechanism of signals and slots

It is really important to keep your curiosity and to explore what on earth these properties do. However, please remember to revert the changes you made to the app, as we are about to enter the core part of Qt, that is, signals and slots.

Note

Signals and slots are used for communication between objects. The signals and slots mechanism is a central feature of Qt and probably the part that differs the most from the features provided by other frameworks.

Have you ever wondered why a window closes after the Close button is clicked on? Developers who are familiar with other toolkits would say that the Close button being clicked on is an event, and this event is bound with a callback function that is responsible for closing the window. Well, it's not quite the same in the world of Qt. Since Qt uses a mechanism called signals and slots, it makes the callback function weakly coupled to the event. Also, we usually use the terms signal and slot in Qt. A signal is emitted when a particular event occurs. A slot is a function that is called in response to a particular signal. The following simple and schematic diagram helps you understand the relation between signals, events, and slots:

Understanding the mechanism of signals and slots

Qt has tons of predefined signals and slots, which cover its general purposes. However, it's indeed commonplace to add your own slots to handle the target signals. You may also be interested in subclassing widgets and writing your own signals, which will be covered later. The mechanism of signals and slots was designed to be type-safe because of its requirement of the list of the same arguments. In fact, the slot may have a shorter arguments list than the signal since it can ignore the extras. You can have as many arguments as you want. This enables you to forget about the wildcard void* type in C and other toolkits.

Since Qt 5, this mechanism is even safer because we can use a new syntax of signals and slots to deal with the connections. A conversion of a piece of code is demonstrated here. Let's see what a typical connect statement in old style is:

connect(sender, SIGNAL(textChanged(QString)), receiver, SLOT(updateText(QString)));

This can be rewritten in a new syntax style:

connect(sender, &Sender::textChanged, receiver, &Receiver::updateText);

In the traditional way of writing code, the verification of signals and slots only happens at runtime. In the new style, the compiler can detect the mismatches in the types of arguments and the existence of signals and slots at compile time.

Note

As long as it is possible, all connect statements are written in the new syntax style in this book.

Now, let's get back to our application. I'll show you how to display some words in a plain text edit when the Hello button is clicked on. First of all, we need to create a slot since Qt has already predefined the clicked signal for the QPushButton class. Edit mainwindow.h and add a slot declaration:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void displayHello();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

As you can see, it's the slots keyword that distinguishes slots from ordinary functions. I declared it private to restrict access permission. You have to declare it a public slot if you need to invoke it in an object from other classes. After this declaration, we have to implement it in the mainwindow.cpp file. The implementation of the displayHello slot is written as follows:

void MainWindow::displayHello()
{
    ui->plainTextEdit->appendPlainText(QString("Hello"));
}

It simply calls a member function of the plain text edit in order to add a Hello QString to it. QString is a core class that Qt has introduced. It provides a Unicode character string, which efficiently solves the internationalization issue. It's also convenient to convert a QString class to std::string and vice versa. Besides, just like the other QObject classes, QString uses an implicit sharing mechanism to reduce memory usage and avoid needless copying. If you don't want to get concerned about the scenes shown in the following code, just take QString as an improved version of std::string. Now, we need to connect this slot to the signal that the Hello push button will emit:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    connect(ui->helloButton, &QPushButton::clicked, this, &MainWindow::displayHello);
}

What I did is add a connect statement to the constructor of MainWindow. In fact, we can connect signals and slots anywhere and at any time. However, the connection only exists after this line gets executed. So, it's a common practice to have lots of connect statements in the construction functions instead of spreading them out. For a better understanding, run your application and see what happens when you click on the Hello button. Every time you click, a Hello text will be appended to the plain text edit. The following screenshot is what happened after we clicked on the Hello button three times:

Understanding the mechanism of signals and slots

Getting confused? Let me walk you through this. When you clicked on the Hello button, it emitted a clicked signal. Then, the code inside the displayHello slot got executed, because we connected the clicked signal of the Hello button to the displayHello slot of MainWindow. What the displayHello slot did is that it simply appended Hello to the plain text edit.

It may take you some time to fully understand the mechanism of signals and slots. Just take your time. I'll show you another example of how to disconnect such a connection after we clicked on the Hola button. Similarly, add a declaration of the slot to the header file and define it in the source file. I pasted the content of the mainwindow.h header file, as follows:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void displayHello();
    void onHolaClicked();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

It's only declaring a onHolaClicked slot that differed from the original. Here's the content of the source file:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    connect(ui->helloButton, &QPushButton::clicked, this, &MainWindow::displayHello);
    connect(ui->holaButton, &QPushButton::clicked, this, &MainWindow::onHolaClicked);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::displayHello()
{
    ui->plainTextEdit->appendPlainText(QString("Hello"));
}

void MainWindow::onHolaClicked()
{
    ui->plainTextEdit->appendPlainText(QString("Hola"));
    disconnect(ui->helloButton, &QPushButton::clicked, this, &MainWindow::displayHello);
}

You'll find that the Hello button no longer works after you clicked on the Hola button. This is because in the onHolaClicked slot, we just disconnected the binding between the clicked signal of helloButton and the displayHello slot of MainWindow. Actually, disconnect has some overloaded functions and can be used in a more destructive way. For example, you may want to disconnect all connections between a specific signal sender and a specific receiver:

disconnect(ui->helloButton, 0, this, 0);

If you want to disconnect all the slots associated with a signal, since a signal can be connected to as many slots as you wish, the code can be written like this:

disconnect(ui->helloButton, &QPushButton::clicked, 0, 0);

We can also disconnect all the signals in an object, whatever slots they might be connected to. The following code will disconnect all the signals in helloButton, which of course includes the clicked signal:

disconnect(ui->helloButton, 0, 0, 0);

Just like a signal, a slot can be connected to as many signals as you want. However, there's no such function to disconnect a specific slot from all the signals.

Tip

Always remember the signals and slots that you have connected.

Apart from the new syntax for traditional connections of signals and slots, Qt 5 has offered a new way to simplify such a binding process with C++11 lambda expressions. As you may have noticed, it's kind of tedious to declare a slot in the header file, define it in the source code file, and then connect it to a signal. It's worthwhile if the slot has a lot of statements, otherwise it becomes time consuming and increases the complexity. Before we go any further, we need to turn on C++11 support on Qt. Edit the pro file (layout_demo.pro in my example) and add the following line to it:

CONFIG += c++11

Note

Note that some old compilers don't support C++11. If this happens, upgrade your compiler.

Now, you need to navigate to Build | Run qmake to reconfigure the project properly. If everything is okay, we can go back to editing the mainwindow.cpp file. This way, there is no need to declare a slot and define and connect it. Just add a connect statement to the construction function of MainWindow:

connect(ui->bonjourButton, &QPushButton::clicked, [this](){
    ui->plainTextEdit->appendPlainText(QString("Bonjour"));
});

It's very straightforward, isn't it? The third argument is a lambda expression, which was added to C++ since C++11.

Note

For more details about lambda expression, visit http://en.cppreference.com/w/cpp/language/lambda.

This pair of signal and slot connection is done if you don't do need to to disconnect such a connection. However, if you need, you have to save this connection, which is a QMetaObject::Connection type. In order to disconnect this connection elsewhere, it would be better to declare it as a variable of MainWindow. So the header file becomes as follows:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void displayHello();
    void onHolaClicked();

private:
    Ui::MainWindow *ui;
    QMetaObject::Connection bonjourConnection;
};

#endif // MAINWINDOW_H

Here, I declared bonjourConnection as an object of QMetaObject::Connection so that we can save the connection dealing with an unnamed slot. Similarly, the disconnection happens in onHolaClicked, so there won't be any new Bonjour text on screen after we click on the Hola button. Here is the content of mainwindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    connect(ui->helloButton, &QPushButton::clicked, this, &MainWindow::displayHello);
    connect(ui->holaButton, &QPushButton::clicked, this, &MainWindow::onHolaClicked);
    bonjourConnection = connect(ui->bonjourButton, &QPushButton::clicked, [this](){
        ui->plainTextEdit->appendPlainText(QString("Bonjour"));
    });
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::displayHello()
{
    ui->plainTextEdit->appendPlainText(QString("Hello"));
}

void MainWindow::onHolaClicked()
{
    ui->plainTextEdit->appendPlainText(QString("Hola"));
    disconnect(ui->helloButton, &QPushButton::clicked, this, &MainWindow::displayHello);
    disconnect(bonjourConnection);
}

Tip

Downloading the example code

You can download the example code files from your account at http://www.packtpub.com for all the Packt Publishing books you have purchased. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

This is indeed another new usage of disconnect. It takes in a QMetaObject::Connection object as the only argument. You'll thank this new overloaded function if you're going to use the lambda expression as a slot.

Connecting two signals

Due to the weak couplings of the Qt signals and slot mechanisms, it is viable to bind signals to each other. It may sound confusing, so let me draw a diagram to make it clear:

Connecting two signals

When an event triggers a specific signal, this emitted signal could be another event, which will emit another specific signal. It is not a very common practice, but it tends to be useful when you deal with some complex signals and slot connection networks, especially when tons of events lead to the emission of only a few signals. Although it definitely increases the complexity of the project, binding these signals could simplify the code a lot. Append the following statement to the construction function of MainWindow:

connect(ui->bonjourButton, &QPushButton::clicked, ui->helloButton, &QPushButton::clicked);

You'll get two lines in a plain text edit after you click on the Bonjour button. The first line is Bonjour and the second one is Hello. Apparently, this is because we coupled the clicked signal of the Bonjour button with the clicked signal of the Hello button. The clicked signal of the latter has already been coupled with a slot, which results in the new text line, Hello. In fact, it has the same effect as the following statement:

connect(ui->bonjourButton, &QPushButton::clicked, [this](){
    emit ui->helloButton->clicked();
});

Basically, connecting two signals is a simplified version of connecting a signal and a slot, while the slot is meant to emit another signal. As for priority, the slot(s) of the latter signal will be handled when the event loop is returned to the object.

However, it is impossible to connect two slots because the mechanism requires a signal while a slot is considered a receiver instead of a sender. Therefore, if you want to simplify the connection, just wrap these slots as one slot, which can be used for connections.

Creating a Qt Quick application

We already covered how to create a Qt (C++) application. How about giving the newly introduced Qt Quick application development a try? Qt Quick was introduced in Qt 4.8 and it is now becoming mature in Qt 5. Because the QML file is usually platform-independent, it enables you to develop an application for multiple targets, including mobile operating systems with the same code.

In this chapter, I'll show you how to create a simple Qt Quick application based on Qt Quick Controls 1.2, as follows:

  1. Create a new project named HelloQML.
  2. Select Qt Quick Application instead of Qt Widgets Application, which we chose previously.
  3. Select Qt Quick Controls 1.2 when the wizard navigates you to Select Qt Quick Components Set.

Qt Quick Controls has been introduced since Qt 5.1 and is highly recommended because it enables you to build a complete and native user interface. You can also control the top-level window properties from QML. Getting confused by QML and Qt Quick?

Note

QML is a user interface specification and programming language. It allows developers and designers alike to create highly performant, fluidly animated, and visually appealing applications. QML offers a highly readable, declarative, JSON-like syntax with support for imperative JavaScript expressions combined with dynamic property bindings.

While Qt Quick is the standard library for QML, it sounds like the relation between STL and C++. The difference is that QML is dedicated to user interface design and Qt Quick includes a lot of visual types, animations, and so on. Before we go any further, I want to inform you that QML is different from C++ but similar to JavaScript and JSON.

Edit the main.qml file under the root of the Resources file, qml.qrc, which Qt Creator has generated for our new Qt Quick project. Let's see how the code should be:

import QtQuick 2.3
import QtQuick.Controls 1.2

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello QML")

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

    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")
    }
}

If you have ever touched Java or Python, the first two lines won't be too unfamiliar to you. It simply imports Qt Quick and Qt Quick Controls, and the number following is the version of the library. You may need to change the version if there is a newer library. Importing other libraries is a common practice when developing Qt Quick applications.

The body of this QML source file is actually in the JSON style, which enables you to understand the hierarchy of the user interface through the code. Here, the root item is ApplicationWindow, which is basically the same thing as MainWindow in the previous topics, and we use braces to enclose the statements just like in a JSON file. Although you could use a semicolon to mark an ending of a statement just like we do in C++, there is no need to do this. As you can see, the property definition needs a colon if it's a single-line statement and enclosing braces if it contains more than one subproperty.

The statements are kind of self explanatory and they are similar to the properties that we saw in the Qt Widgets application. A qsTr function is used for internationalization and localization. Strings marked by qsTr could be translated by Qt Linguist. In addition to this, you don't need to care about QString and std::string any more. All the strings in QML are encoded in the same coding as the QML file and the QML file is created in UTF-8 by default.

As for the signals and slots mechanism in Qt Quick, it's easy if you only use QML to write the callback function to the corresponding slot. Here, we execute Qt.quit() inside the onTriggered slot of MenuItem. It's viable to connect the signal of a QML item to a C++ object's slot, which I'll introduce later.

When you run this application in Windows, you can barely find the difference between the Text item and the Label item. However, on some platforms, or when you change the system font and/or its color, you'll find that Label follows the font and the color scheme of the system, while Text doesn't. Although you can use the properties of Text to customize the appearance of Label, it would be better to use the system settings to keep the looks of the application native. Well, if you run this application right now, it will appear similar to what is shown in the following screenshot:

Creating a Qt Quick application

Because there is no separate UI file for the Qt Quick applications, only a QML file, we use the anchors property to position the items, and anchors.centerIn will position the item in the center of the parent. There is an integrated Qt Quick Designer in Qt Creator, which could help you design the user interface of a Qt Quick application. If you need it, just navigate to Design mode when you're editing a QML file. However, I suggest you stay in Edit mode to understand the meaning of each statement.

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.

Summary

In this chapter, we learned the fundamentals of Qt, which included steps for how to create a Qt application. Then, we had a walk-through of both Qt Widgets and Qt Quick, and how to change the layout. Finally, we rounded off by covering an important concept about the mechanism of signals and slots.

In the next chapter, we will have a chance to put this knowledge into practice and get started on building a real-world, and of course cross-platform, Qt application.

Left arrow icon Right arrow icon

Description

If you are a programmer looking for a truly cross-platform GUI framework to help you save your time by side-stepping the incompatibility between different platforms and building applications using Qt 5 for multiple targets, then this book is most certainly intended for you. It is assumed that you have a basic programming experience of C++ and fundamental knowledge about Qt.

What you will learn

  • Create graphical user interface applications with a customized layout and widgets Explore how the Model-View-Controller architecture works and relevant classes in Qt Develop a configurable application that is able to save and restore its own settings Write both static and dynamic plugins for Qt Widgets and Qt Quick applications Convert your single-threaded application to a nonblocking application by moving part of the application to another thread Enable your applications to support other languages dynamically
Estimated delivery fee Deliver to Germany

Premium delivery 7 - 10 business days

€17.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Mar 30, 2015
Length: 272 pages
Edition : 1st
Language : English
ISBN-13 : 9781784394615
Category :
Languages :
Tools :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Estimated delivery fee Deliver to Germany

Premium delivery 7 - 10 business days

€17.95
(Includes tracking information)

Product Details

Publication date : Mar 30, 2015
Length: 272 pages
Edition : 1st
Language : English
ISBN-13 : 9781784394615
Category :
Languages :
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
€18.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
€189.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts
€264.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total 115.97
Application Development with Qt Creator - Second Edition
€36.99
QT5 Blueprints
€41.99
Mastering Qt 5
€36.99
Total 115.97 Stars icon

Table of Contents

11 Chapters
1. Creating Your First Qt Application Chevron down icon Chevron up icon
2. Building a Beautiful Cross-platform Clock Chevron down icon Chevron up icon
3. Cooking an RSS Reader with Qt Quick Chevron down icon Chevron up icon
4. Controlling Camera and Taking Photos Chevron down icon Chevron up icon
5. Extending Paint Applications with Plugins Chevron down icon Chevron up icon
6. Getting Wired and Managing Downloads Chevron down icon Chevron up icon
7. Parsing JSON and XML Documents to Use Online APIs Chevron down icon Chevron up icon
8. Enabling Your Qt Application to Support Other Languages Chevron down icon Chevron up icon
9. Deploying Applications on Other Devices Chevron down icon Chevron up icon
10. Don't Panic When You Encounter These Issues Chevron down icon Chevron up icon
Index Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
(9 Ratings)
5 star 33.3%
4 star 55.6%
3 star 0%
2 star 0%
1 star 11.1%
Filter icon Filter
Top Reviews

Filter reviews by




Bill Armstrong Jul 13, 2015
Full star icon Full star icon Full star icon Full star icon Full star icon 5
I was originally reluctant to buy this book because a lot of the advertising was poorly written, and I thought the book could be a pain to read. It must have had the services of an excellent editor because it is very easy to read and understand. The exposition is suitable for someone starting out in Qt 5, and there are lots of examples. A good choice.
Amazon Verified review Amazon
WEMPE Jan 26, 2016
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Ich steige gerade komplett neu in die Welt von Qt und C++ ein. Das Buch bietet ein schnellen Einstieg in die Welt von Qt. Viele Themen werden soweit angeschnitten, dass es leicht fällt die Richtung zu erkennen, in der man weiter forschen muss.
Amazon Verified review Amazon
Amazon Customer Jun 26, 2017
Full star icon Full star icon Full star icon Full star icon Full star icon 5
On time. No problems.
Amazon Verified review Amazon
AOT Nov 18, 2015
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
No me lo he leído entero, pero Qt5 está lleno de secretos, este libro os ahorrará tiempo! No es un reference guide universal.
Amazon Verified review Amazon
TB Jan 14, 2016
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
I've been working with C/C++ for a few years now, and with Qt for 1-2 years...mainly with Qt4 in embedded systems. I have a couple of the (very thorough) Qt4-based books that are available here on Amazon, and they are very good. In fact, they are almost TOO good from the standpoint that they nearly overwhelm you with information. But as reference material, they are extremely valuable. That being said however, when I saw that this book was dealing with Qt5 I wanted to go ahead and read it.I read both of the reviews posted previous to mine, before buying the book. Then I purchased the Kindle version of this book and worked through the first couple of chapters. I can definitely see the criticism(s) noted in Keith Peter's review. It's pretty apparent that this book did not have a good Technical Editor to go through it, because there are a number of simple errors that should NOT have made it through. For example in chapter 2, here's one such example:"...In other cases, we have to explicitly set the parent for a QObject child so that the parent can take over its ownership and manage the release of its memory. Hence, we pass the QObject parent, which is this, a MainWindow class to the constructor of QTimer."It's unfortunate that the author doesn't point out that the "this" pointer is a pointer to the instance of a class that is currently being referenced. In other words, "this" isn't a class...it's a pointer to an instance of a class.There are a number of similar such errors in the first two chapters, but overall the intent of the author is very good I think. But as I stated above, the book is in dire need of a good Technical Editor to go through and point this out to the author. I have served as a Technical Editor for a book on embedded systems, and it's not an easy task. It take many hours of work to go through a book such as this, but the result is well worth the effort.So overall I'll want to come back and revisit this review after finishing the book, but for now I would have to give it a 4-stars due to poor editing. I would have to agree with Keith on this point. I would also add that you really do need to have some C++ experience before working through this book, as that is assumed--and it would also be most helpful to know something about Qt (and Qt Creator) before reading this book. While it's not absolutely imperative that you have used Qt before, there are many times that the author chooses not to go into elaborate detail on a take he asks you to perform. If you are at least somewhat experienced with Qt Creator you will have little problem getting things accomplished--but you might struggle a little but if you've never used the IDE before. On the other hand it will make you dig more for the answer(s), so I suppose that's not all bad.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela