Discover millions of ebooks, audiobooks, and so much more with a free trial

Only $11.99/month after trial. Cancel anytime.

Mastering Qt 5
Mastering Qt 5
Mastering Qt 5
Ebook862 pages9 hours

Mastering Qt 5

Rating: 0 out of 5 stars

()

Read preview

About this ebook

This book will appeal to developers and programmers who would like to build GUI-based applications. Knowledge of C++ is necessary and the basics of Qt would be helpful.
LanguageEnglish
Release dateDec 15, 2016
ISBN9781786464606
Mastering Qt 5

Related to Mastering Qt 5

Related ebooks

Programming For You

View More

Related articles

Reviews for Mastering Qt 5

Rating: 0 out of 5 stars
0 ratings

0 ratings0 reviews

What did you think?

Tap to rate

Review must be at least 10 words

    Book preview

    Mastering Qt 5 - Guillaume Lazar

    problem.

    Chapter 1.  Get Your Qt Feet Wet

    If you know C++ but have never touched Qt, or if you have made some intermediate Qt applications, this chapter will ensure that your Qt foundations are safe before studying advanced concepts in the following chapters.

    We will teach you to create a simple todo application using Qt Creator. This application will display a list of tasks that you can create/update/delete. We will cover the Qt Creator and Qt Designer interfaces, an introduction to the signal/slot mechanism, the creation of a custom widget with custom signals/slots, and its integration into your application.

    You will implement a todo app using new C++14 semantics: lambdas, auto variables, and for loops. Each one of these concepts will be explained in depth and will be used throughout the book.

    At the end of this chapter, you will be able to create a desktop application with a flexible UI using Qt widgets and new C++ semantics.

    In this chapter, we will cover the following topics:

    Qt project basic structure

    Qt Designer interface

    UI fundamentals

    Signals and slots

    Custom QWidget

    C++14 lambda, auto, for each

    Creating a project

    The first thing to do is to start Qt Creator.

    In Qt Creator, you can create a new Qt project via File | New File or Project | Application | Qt Widgets Application | Choose.

    The wizard will then guide you through four steps:

    Location: You must choose a project name and a location.

    Kits: Target platforms that your project aims at (Desktop, Android, and so on).

    Details: Base class information and name for the generated class.

    Summary: Allows you to configure your new project as a subproject and automatically add it to a version control system.

    Even if all default values can be kept, please at least set a useful project name such as todo or TodoApp. We won't blame you if you want to call it Untitled or Hello world.

    Once done, Qt Creator will generate several files that you can see in the Projects hierarchy view:

    The .pro file is Qt's configuration project file. As Qt adds specific file formats and C++ keywords, an intermediate build step is performed, parsing all files to generate final files. This process is done by qmake, an executable from the Qt SDK. It will also generate the final Makefiles for your project.

    A basic .pro file generally contains:

    Qt modules used (core, gui, and so on)

    Target name (todo, todo.exe, and so on)

    Project template (app, lib, and so on)

    Sources, headers, and forms

    There are some great features that come with Qt and C++14. This book will showcase them in all its projects. For GCC and CLANG compilers, you must add CONFIG += c++14 to the .pro file to enable C++14 on a Qt project, as shown in the following code:

    QT      += core gui

    CONFIG  += c++14

    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

    TARGET = todo

    TEMPLATE = app

    SOURCES += main.cpp \

              MainWindow.cpp

    HEADERS  += MainWindow.h \

    FORMS    += MainWindow.ui \

    The MainWindow.h and MainWindow.cpp files are the headers/sources for the MainWindow class. These files contain the default GUI generated by the wizard.

    The MainWindow.ui file is your UI design file in XML format. It can be edited more easily with Qt Designer. This tool is a WYSIWYG (What You See Is What You Get) editor that helps you to add and adjust your graphical components (widgets).

    Here is the main.cpp file, with its well-known function:

    #include MainWindow.h

    #include

    int main(int argc, char *argv[])

    {

        QApplication a(argc, argv);

        MainWindow w;

        w.show();

        return a.exec();

    }

    As usual, the main.cpp file contains the program entry point. It will, by default, perform two actions:

    Instantiate and show your main window

    Instantiate a QApplication and execute the blocking main event loop

    This is the bottom-left toolbar for Qt Creator:

    Use it to build and start your todo application in debug mode:

    Check that the project is in Debug build mode.

    Use the hammer button to build your project.

    Start debugging using the green Play button with a little blue bug.

    You will discover a wonderful and beautifully empty window. We will rectify this after explaining how this MainWindow is constructed:

    An empty MainWindow screenshot

    Tip

    Qt tip

    Press Ctrl B (for Windows/Linux) or Command B (for Mac) to build your project

    Press F5 (for Windows / Linux) or Command +R (for Mac) to run your application in debug mode

    MainWindow structure

    This generated class is a perfect yet simple example of Qt framework usage; we will dissect it together. As mentioned previously, the MainWindow.ui file describes your UI design and MainWindow.h/ MainWindow.cpp is the C++ object where you can manipulate the UI with code.

    It is important to take a look at the header file MainWindow.h. Our MainWindow object inherits from Qt's QMainWindow class:

    #include

    namespace Ui {

    class MainWindow;

    }

    class MainWindow : public QMainWindow

    {

        Q_OBJECT

    public:

        explicit MainWindow(QWidget *parent = 0);

        ~MainWindow();

    private:

        Ui::MainWindow *ui;

    };

    As our class inherits from the QMainWindow class, on top of the header file, we add the corresponding include. The second part is the forward declaration of the Ui::MainWindow, as we only declare a pointer.

    The Q_OBJECT can look a little strange to a non-Qt developer. This macro allows the class to define its own signals/slots and more globally Qt's meta-object system. These features will be covered later in this chapter.

    This class defines a public constructor and destructor. The latter is pretty common. But the constructor takes a parameter parent. This parameter is a QWidget pointer that is null by default.

    A QWidget is a UI component. It can be a label, a textbox, a button, and so on. If you define a parent-child relationship between your window, layout, and other UI widgets, memory management of your application will be easier. Indeed, in this case, deleting the parent is enough because its destructor will take care of also deleting its child, which in turn will delete its children and so on.

    Our MainWindow class extends QMainWindow from the Qt framework. We have a ui member variable in the private fields. The type is a pointer of Ui::MainWindow, which is defined in the ui_MainWindow.h file generated by Qt. It's the C++ transcription of the UI design file MainWindow.ui. The ui member variable will allow you to interact with your UI components (QLabel, QPushButton, and so on) from C++, as shown in the following figure:

    Tip

    C++ tip

    If your class only uses pointers or references for a class type, you can avoid including the header by using forward declaration. That will drastically reduce compilation time.

    Now that the header part is done, we can talk about the MainWindow.cpp source file.

    In the following code snippet, the first include is our class header. The second one is the include required by the generated class Ui::MainWindow. This include is required as we only use a forward declaration in the header:

    #include MainWindow.h

    #include ui_MainWindow.h

    MainWindow::MainWindow(QWidget *parent) :

        QMainWindow(parent),

        ui(new Ui::MainWindow)

    {

        ui->setupUi(this);

    In many cases, Qt generates a good piece of code using the initializer list. The parent argument is used to call the superclass constructor QMainWindow. Our private member variable ui is also initialized now.

    Now that ui is initialized, we must call the setupUi function to initialize all widgets used by the MainWindow.ui design file:

    As we initialize a pointer in the constructor, it must be cleaned in the destructor:

    MainWindow::~MainWindow()

    {

        delete ui;

    }

    Qt Designer

    Qt Designer is a major tool for developing Qt applications. This WYSIWYG editor will help you easily design your GUI. If you switch between Edit mode and Design mode for the MainWindow.ui file, you will see the real XML content and the designer:

    The designer displays several parts:

    Form Editor: This is a visual representation of the form (empty for now)

    Widget Box: This contains all widgets that can be used with your form

    Object Inspector: This displays your form as a hierarchical tree

    Property Editor: This enumerates the properties of the selected widget

    Action Editor/Signal & Slots Editor: This handles connections between your objects

    It's time to embellish this empty window! Let's drag and drop a Label widget from the Display Widgets section on the form. You can change the name and the text properties from the properties editor.

    As we are making a todo application, we suggest these properties:

    objectName: statusLabel

    text: Status: 0 todo/0 done

    This label will later display the count of todo tasks and the count of tasks already done. OK, save, build, and start your application. You should now see your new label in the window.

    You can now add a push button with those properties:

    objectName: addTaskButton

    text: Add task

    You should get a result close to this:

    Tip

    Qt tip

    You can edit the text property of a widget directly on your form by double-clicking on it!

    Signals and slots

    The Qt framework brings a flexible message exchange mechanism through three concepts: signals, slots, and connections:

    A signal is a message sent by an object

    A slot is a function that will be called when this signal is triggered

    The connect function specifies which signal is linked to which slot

    Qt already provides signals and slots for its classes, which you can use in your application. For example, QPushButton has a signal clicked(), which will be triggered when the user clicks on the button. The QApplication class has a slot quit() function, which can be called when you want to terminate your application.

    Here is why you will love Qt signals and slots:

    A slot remains an ordinary function, so you can call it yourself

    A single signal can be linked to different slots

    A single slot can be called by different linked signals

    A connection can be made between a signal and a slot from different objects, and even between objects living inside different threads!

    Keep in mind that, to be able to connect a signal to a slot, their methods' signatures must match. The count, order, and type of arguments must be identical. Note that signals and slots never return values.

    This is the syntax of a Qt connection:

    connect(sender, &Sender::signalName, 

        receiver, &Receiver::slotName);

    The first test that we can do to use this wonderful mechanism is to connect an existing signal with an existing slot. We will add this connect call to the MainWindow constructor:

    MainWindow::MainWindow(QWidget *parent) :

        QMainWindow(parent),

        ui(new Ui::MainWindow)

    {

        ui->setupUi(this);

        connect(ui->addTaskButton, &QPushButton::clicked,

        QApplication::instance(), &QApplication::quit);

    }

    Let's analyze how a connection is done:

    sender: This is the object that will send the signal. In our example, it is the QPushButton named addTaskButton added from the UI designer.

    &Sender::signalName: This is the pointer to the member signal function. Here, we want do something when the clicked signal is triggered.

    receiver: This is the object that will receive and handle the signal. In our case, it is the QApplication object created in main.cpp.

    &Receiver::slotName: This is a pointer to one of the receiver's member slot functions. In this example, we use the built-in quit() slot from Qapplication, which will exit the application.

    You can now compile and run this short example. You will terminate the application if you click on the addTaskButton of your MainWindow.

    Tip

    Qt tip

    You can connect a signal to another signal. The second signal will be emitted when the first one is triggered.

    Now that you know how to connect a signal to an existing slot, let's see how to declare and implement a custom addTask() slot in our MainWindow class. This slot will be called when the user clicks on ui->addTaskButton.

    This is the updated MainWindow.h:

    class MainWindow : public QMainWindow

    {

        Q_OBJECT

    public:

        explicit MainWindow(QWidget *parent = 0);

        ~MainWindow();

    public slots:

        void addTask();

    private:

        Ui::MainWindow *ui;

    };

    Qt uses a specific slot keyword to identify slots. Since a slot is a function, you can always adjust the visibility (public, protected or private) depending on your needs.

    Add this slot implementation in the MainWindow.cpp

    Enjoying the preview?
    Page 1 of 1