qtlabs Documentation - Read the Docs

29
qtlabs Documentation Release Vladimir Poliakov Aug 21, 2017

Transcript of qtlabs Documentation - Read the Docs

Page 1: qtlabs Documentation - Read the Docs

qtlabs DocumentationRelease

Vladimir Poliakov

Aug 21, 2017

Page 2: qtlabs Documentation - Read the Docs
Page 3: qtlabs Documentation - Read the Docs

Contents

1 Introduction 31.1 What is Qt? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.2 Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.3 Toolkit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

2 Getting started with Qt 52.1 Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.2 Qt installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.3 First project in Qt Creator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

3 Lab 1. Qt basics 193.1 Typical main.cpp file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193.2 Qt basic modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203.3 QObject model philosophy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213.4 Conclusion and exercise . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

i

Page 4: qtlabs Documentation - Read the Docs

ii

Page 5: qtlabs Documentation - Read the Docs

qtlabs Documentation, Release

This project aims to give basic knowledges and skills of using Qt framework. There is no special prerequisites, exceptsome essentials in C++.

Contents 1

Page 6: qtlabs Documentation - Read the Docs

qtlabs Documentation, Release

2 Contents

Page 7: qtlabs Documentation - Read the Docs

CHAPTER 1

Introduction

What is Qt?

Qt (“cute”) is the independent technology for cross-platform development of application on desktop, embeddedand mobile operating systems. It consists of toolkit, including tools for development, debugging and deploymentof application, for cross-platform applications. Qt is usually refereed as a C++ framework and a set of tools fordevelopment of graphical interfaces. Indeed, at the current time Qt framework has much more capabilities, includingmulti-threading, networking, and can be easily integrated with other languages, such as Python, Javascript, SQL ,as well as it can be combined with different tools and frameworks, for instance D-Bus and OpenCV. Thus, Qt is aplatform of choice for:

1. Desktop applications

2. Mobile applications

3. Embedded systems:

• in-vehicle systems

• medical equipment

• industrial automation devices

Framework

Qt framework includes next modules:

1. QtCore - Core non-graphical classes used by other modules.

2. QtGUI - Base classes for graphical user interface (GUI) components. Includes OpenGL.

3. QtMultimedia - Classes for audio, video, radio and camera functionality.

4. QtNetwork - Classes to make network programming easier and more portable.

5. QtQuick - A declarative framework for building dynamic applications with custom user interfaces.

3

Page 8: qtlabs Documentation - Read the Docs

qtlabs Documentation, Release

6. QtSQL - Classes for database integration using SQL.

7. QtTest -Classes for unit testing Qt applications and libraries.

Toolkit

Qt toolkit includes different tools for development, such as:

1. Qt Creator - IDE for development, debugging and deployment of application

2. Qt Designer - part of Qt Creator, tool for graphical design of UI

3. Qt Linguist - tool used for internationalization of application.

Mainly, every Qt project can be easily build and deployed without these tools by using different IDEs or editors, but Iwould encourage you to try out Qt Creator cause it is nicely tuned for Qt projects.

4 Chapter 1. Introduction

Page 9: qtlabs Documentation - Read the Docs

CHAPTER 2

Getting started with Qt

This part will explain how to install Qt and how to create your first projectin Qt Creator

Prerequisites

Before we proceed, let’s install some packages we may need in order to build and debug our applications.

Linux

Linux users need few additional packages like:

1. OpenGL - open graphics library for hardware-accelerated rendering

2. GNU Make - a tool which controls the generation of executables and other non-source files of a program

3. GCC - GNU Compiler Collection

4. gdb - GNUdebugger

You can install these packages using following command:

sudo apt-get install gcc g++ gdb make libgl1-mesa-dev

Note: The command above will only work in Debian-like distributions, such as Ubuntu, Linux Mint, KDE Neon, etc.

Windows

No additional software must be installed. Everything should work out of box.

5

Page 10: qtlabs Documentation - Read the Docs

qtlabs Documentation, Release

MacOS

No idea, honestly.

Qt installation

Let’s first start with installation of Qt and proceed with trying it out by creating a simple hello world project:

Note: Installation will use approx. 1.47GiB of disk space.

1. Go to Qt download page and download Qt by picking open source version.

2. After downloading the installer run it. Linux users need to add permission for execution. For that, right click on thefile -> Properties -> set flag ‘is executable’, than it should become executable.

6 Chapter 2. Getting started with Qt

Page 11: qtlabs Documentation - Read the Docs

qtlabs Documentation, Release

3. You can skip creating a Qt account or, obviously, create one.

4. Choose the path you would like to install Qt

2.2. Qt installation 7

Page 12: qtlabs Documentation - Read the Docs

qtlabs Documentation, Release

5. On selecting components page pick the latest version of Qt (5.9.1 at the moment) and Tools.

8 Chapter 2. Getting started with Qt

Page 13: qtlabs Documentation - Read the Docs

qtlabs Documentation, Release

6. Install it!

If everything went good, you shall be able to start Qt Creator. Now, let’s set up the build configuration.

Setting up the build configuration

Before you can start using Qt you need to ensure that the build configuration isset properly. Long story short, config-uration includes selection of a compilerand a version Qt libraries. A combination of these two components (compilerand Qt version) is called a kit and is a corner stone of cross-compilation. Butwe will get back to it later. Now you onyneed to check if the default kit isworking fine. To do that:

1. Start Qt creator.

2.2. Qt installation 9

Page 14: qtlabs Documentation - Read the Docs

qtlabs Documentation, Release

2. Go to Tools -> Options...

3. Select Build & Run in the menu on the left, then pick tab Kits, and check ifthere is an Auto-detected kit. If there isone, select it and check if both C and C++ compilers are set. If both are set, it means that your kit is properly set andyou can skip the rest of this part and start with your first project.

4. If no kit is auto-detected or if auto-dected kit misses Qt version or compilers, you have to set them up manually.

5. To set up Qt version go to Qt versions tab -> Add... ,go to the Qt installation path and search for qmake file insidethat folder. It should be somewhere inside a folder like 5.9/gcc_64/bin or else depending on the platform and versionused.

10 Chapter 2. Getting started with Qt

Page 15: qtlabs Documentation - Read the Docs

qtlabs Documentation, Release

6. To set up compilers go to Compilers tab -> Add, select the proper compiler that you use (usually MinGW forWindows and GCC for Linux) and search for gcc and g++ in the system.

2.2. Qt installation 11

Page 16: qtlabs Documentation - Read the Docs

qtlabs Documentation, Release

After just click ok and that is it! You are ready for your first project!

First project in Qt Creator

Before we start with learning Qt we should first learn how to create and maintain the project in Qt creator:

1. Open Qt Creator, go to the Welcome page, and click Projects -> New Project

2. Since we want to check if everything is working fine, we pick Qt Quick Application and click next

3. Give a name and place for a project. It is always a nice idea to store all projects in one place, so you can create aworkspace and mark it as a default project location.

12 Chapter 2. Getting started with Qt

Page 17: qtlabs Documentation - Read the Docs

qtlabs Documentation, Release

4. Pick a minimal version of Qt libraries. Since we don’t really care about compatability so far, you can leave it as itis. But we also won’t use Qt Designer this time, so unmark “With ui.qml file”.

2.3. First project in Qt Creator 13

Page 18: qtlabs Documentation - Read the Docs

qtlabs Documentation, Release

5. Pick a kit to use. Most probably you will only have one kit, thus you have not so many options. But interestingpart is hidden in details. Here you can define a place and a name for a building directory. By default it is located onthe same level as the project folder, but you can choose any other level or a foldr name, it should not bring you anytroubles except a warning. You can also see that there three possible versions: debug, release, and progile. You canfreely use any of them, the differnce is only that debugging and profiling versions add some information to executablefor debugging/profiling.

14 Chapter 2. Getting started with Qt

Page 19: qtlabs Documentation - Read the Docs

qtlabs Documentation, Release

6. Finish the creation

After finishing the creation Creator will open the project and show main.qml file.

On the left side you can see the structure of a project. It include .pro file, you won’t usually change, it is just specifiesQt modules used in the project and sources and headers. Then the project has sources and headers sections. Since wedon’t have any headers in our project, so you shall only be able to see the Sources section. Next, there is a resourcesection. We will later talk about what resources are, but long story short those are collections of files that will beincluded into executable, so later on you will only need to put one file in the target machine for deployment instead ofbunch of pictures and conf files.

You can see that main.qml represents some basic “hello world”-like template. Let’s change it now for something justa bit fancier to get to know how to add files to a project. Let it be clocks, for example.

First update the main.cpp and main.qml files. Replace the contents ofmain.qml with following lines:

import QtQuick 2.6import QtQuick.Window 2.2

Image {visible: trueid: backgroundsource: "pics/clocks_background.png"

Image {id: minuteArrow

2.3. First project in Qt Creator 15

Page 20: qtlabs Documentation - Read the Docs

qtlabs Documentation, Release

source: "pics/clocks_minute_arrow.png"x: parent.width/2 - minuteArrowRotation.origin.xy: parent.height/2 - minuteArrowRotation.origin.y

transform: Rotation {id: minuteArrowRotationorigin.x: minuteArrow.width/2origin.y: minuteArrow.height - minuteArrow.width/2

Behavior on angle {RotationAnimation { duration: 400; direction:

→˓RotationAnimation.Clockwise}}

}}

Image {id: hourArrowsource: "pics/clocks_hour_arrow.png"x: parent.width/2 - width/2y: parent.height/2 - height + width/2

transform: Rotation {id: hourArrowRotationorigin.x: hourArrow.width/2origin.y: hourArrow.height - minuteArrow.width/2

Behavior on angle {RotationAnimation { duration: 400; direction:

→˓RotationAnimation.Clockwise}}

}}

Timer {interval: 60000repeat: truerunning: truetriggeredOnStart: trueonTriggered: {

var today = new Date()hourArrowRotation.angle = ((today.getHours()%12) * 30)minuteArrowRotation.angle = today.getMinutes() * 6

}}

}

QML may now look a bit weird, but later yu will see that it is very useful when implementing GUI. Next, openmain.cpp file and replace its contents with next lines:

16 Chapter 2. Getting started with Qt

Page 21: qtlabs Documentation - Read the Docs

qtlabs Documentation, Release

#include <QGuiApplication>#include <QQuickView>

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

QGuiApplication app(argc, argv);

QQuickView view;view.setSource(QUrl(QStringLiteral("qrc:/main.qml")));

view.setFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnBottomHint);view.setX(1150);view.setY(20);view.setColor(QColor(Qt::transparent));view.show();

return app.exec();}

No we need to add to the project images that we are going to use in the project. You can download pics from githubqtlabs repo in src/firstproject/pics. Create a new directory called pics inside the project and put the downloaded picsinto that folder. Now you need to add them to a project resources. To add new files to resources right click on qml.qrc-> Add existing... and choose all pics you need (hold Ctrl or Shift for multi-picking). Adding sources is similiar toadding resources, you only need to right click on sources or headers and add new or existing files.

Note: To add a file to a project right click on any section (folder) of the project -> Add new(add existing..)

To add file to a project right click on the .qrc file -> Add new(add existing..)

To delete file from a project right on the file -> Remove

From now on you should be able to run your first app. Click Run in the bottom corner. Your application shall run as abottom window, so hide other windows to check it out. Our application has frameless window, so in order to close itjust click Stop button in Qt creator above Application output section. Congratulations! You have just finised your firstapp. Try now just to tune it a bit:

1. Clock arrows move to slow. Try to find a way to make the minute arrow act like a second arrow and the hour arrowact like a minute arrow

Hint: Search main.qml for the answer

2. Why should our app run on the bottom? Let’s move it to foreground!

Hint: You should probably delete something in main.cpp

2.3. First project in Qt Creator 17

Page 22: qtlabs Documentation - Read the Docs

qtlabs Documentation, Release

18 Chapter 2. Getting started with Qt

Page 23: qtlabs Documentation - Read the Docs

CHAPTER 3

Lab 1. Qt basics

This chapter will guide you through corner stones of C++ based application development using Qt. We will start withoverview of typical main.cpp file for Qt project, then proceed with contents of C++ based Qt basic modules, such asQtCore, QtGui, and QtWidgets. Later on we will look at QObject class, which is the corner stone of Qt.

Typical main.cpp file

Let’s first look at the example of main.cpp:

1 #include <QApplication>2 #include <QLabel>3

4 int main(int argc, char** argv)5 {6 QApplication app(argc, argv);7 QLabel("Hello world!");8 lbl.show();9 return app.exec();

10 }

You can see now that it is lot like any other C++ program’s main file. It goes as following:

1. Declare inclusions. These can be user headers as well as precompiled Qt libraries, if any Qt classes are used directlyin main function. In the above we use QLabel and QApplication, thus we declare them before using in main().

2. Create an instance of QApplication class. This object controls and maintains the application that we create. Onlyone instance of QApplication is allowed in one program.

3. Create an instance of QLabel. After creating Qt elements are usually invisible, so we have to call show() in orderto make it visible. In this case QLabel object is the root object, which means that it will be created as an separatewindow, and the applicaion will exit once this window is closed.

4. Last line launches the execution of the application, which runs till the moment QApplication::exit() is called.

19

Page 24: qtlabs Documentation - Read the Docs

qtlabs Documentation, Release

Note: Try to create two instances of QLabel inside one application. Are they shown in separate windows? If so, willthe application exit if you close one of them? Now try to set the first label as a parent for the second label. Refer toQLabel members list. What happens now? Are both labels shown in one window?

Qt basic modules

Qt library includes more than 500 classes, which cover the most part of OS functionality. But no worries, you don’thave remeber them all. Due to nice modulariztion you only need to have an idea in mind of which module can includefunctionality you need, and then go through module classes list in search of a relevant class.

Any Qt based program must include one or few of following modules: QtCore, QtGui, QtWidgets, QtQuick, QtQML.

Note: Some of modules above will only work in combination with others. For instance, QtQuick is used along withQtQML module.

In the previous excersise you got in touch with some Qt classes, namely QApplication and QLabel. Let’s now list Qtbasic C++ modules and specify the example classes those modules include:

Module

Declaration in .pro

Description and classes included

QtCore core Set of basic classes not related to GUI

• containers: QList, QVector, QMap, QVariant

• io classes: QIODevice, QFile

• timers: QTimer

• date and time: QDate, QTime

• events: QEvent

• settings: QSettings

• animation: QAbstractAnimation

• QCoreAppication

• QObject, a corner stone of any Qt class

• multi-threading/processing: QThread, QProcess

QtGui gui Set of classes for window system integration, OpenGL integration, pallette and cursor shapehandling, etc.

• QWindow

• QGuiApplication, inherits QCoreApplication

QtWidgets widgets Includes widget classes, building blocks for GUI

• QWidget, the basic class for any widget

• indication: QLabel, QLCDNumber

• layout: QHBoxLayout, QVBoxLayout

20 Chapter 3. Lab 1. Qt basics

Page 25: qtlabs Documentation - Read the Docs

qtlabs Documentation, Release

• buttons: QPushButton, QCheckButton

• scrolls: QSlider, QScrollBar

• input: QLineEdit, QSpinBox

• pics: QImage, QPixmap

• painting: QPainter, QBrush, QPen

QObject model philosophy

QObject is a base class for almost each class in Qt. But what is exactly hidden in it? First of all, QObject classis respnosble for creating hyerarchical model in application, what allows developer not to care about maintaing thememory while creating and deleting objects. You can pass the parent for an object as a parameter on creation:

QObject(QObject* parentObject = 0)

As you can see, default value for this parameter is zero, so if you can skip it if you want to create a root object. Anotherway to set the parent is to call setParent() function. But what do we need parent-children relationship for? Let’s lookat the short example:

QObject* obj1 = new QObject;QObject* obj2 = new QObject(obj1);QObject* obj3 = new QObject(obj2);QObject* obj4 = new QObject(obj1);

You can see that hyerarchy for the program above goes as follows:

Now, if we call deleteLater() method of obj3 or obj4, it will only delete obj3 or obj4 respectivly. In contrast, ifwe call obj2.deleteLater() it will delete obj2 along with obj3. Finally, if we call obj1.deleteLater()we will destroy all four objects. Thus, calling deleteLater() method deletes the instance and all its children.

Note: Usually, every object in Qt application should be created by calling new and deleted with deleteLater()

3.3. QObject model philosophy 21

Page 26: qtlabs Documentation - Read the Docs

qtlabs Documentation, Release

method. Excptions are objects with no parents or temporal objects, like objetc that were created to be passed as anargument, for instance lbl.setPixmap(QPixmap(":/background.png")), where QPixmap object is usedas an argument for setPixmap function and does not even have a name.

But it’s not the only reason why we need parent concept. You can access the list of children from object by callingchildren(), or you can search for specific child using findChild() function.

For widgets parent-children relation looks even more interesting. Every child widget can be only rendered inside itsparent. For instance, following example shows two QPushButton objects created on top of QLabel:

QLabel* lbl = new QLabel;lbl->setPixmap(QPixmap(":/background.png"));

QPushButton* pb1 = new QPushButton("Button 1", lbl);QPushButton* pb2 = new QPushButton("Button 2", lbl);pb2->move(pb1->width(),0);

It makes the answer for the previous excersice obvious. Since both widgets did not have a parent, they both werecreated as separate windows.

Signals and slots

Last and the most important about QObject is the signal-slot connection feature. The concept of signals and slots isvery simple and that is why it is so good:

1. Every object of class inherited from QObject can transimit and receive signals. 2. Every object of class inheritedfrom QObject can have one or few slots. Slot is a function that is called when a signal connected to it is received. 3.Every signal can be connected to one or few slots, internal(signal and slot are inside one object) and external (signaland slot are in different objects). 4. Each signal can have one or few argumentsthat will be passed to the slot. 5.Signal and slot connection can be performed in any part of the program. 6. When one objectstaking part in connetionis destructed, signal and slot are automatically disconnected.

Of course, there are few issues of using signal-slot mechanism:

1. There is no compiling-time checking of connect() function, so if something is wrong with connect() you willonly be able to see it after starting the application. 2. Signal-slot connection works a bit slower than direct call offunction. You won’t see it, probably, but still it is good to know. 3. by default signal-slot connection works in queuedway, which means that some time will pass between emiting a signal and calling a dedicated slot. 4. Class that utilizessignals and slots must be inherited from QObject or one of QObject successors.

22 Chapter 3. Lab 1. Qt basics

Page 27: qtlabs Documentation - Read the Docs

qtlabs Documentation, Release

Signals

Signals in Qt is nothing but functions with the capability of sending messages. Signals are always public in Qt5,Which means that you can emit signals that are defined in predecessor class as well as you can emit signal that youhave defined by yourself.To create and use a signal:

1. Put Q_OBJECT macro in header file right below the opening bracket like this:

class MyClass: public QObject{

Q_OBJECT

2. Declare the signal in class in signals section:

signals:void mySignal(int arg1);

Note: Arguments you want to pass to slot should be specified inside backets, not as a return value.

3. Whenever you want to emit the signal, just call emit:

int a = 10;emit mySignal(a);

Here you emit mySignal() with 10 as an argument. Later on you will see that almost anything can be used as anargument, what makes it especially usefull when using object pointers as arguments.

Slots

Slot in Qt is a function that can be called if the dedicated signal is triggered. Still, slots can also be called as a normalfunction. Moreover, slots can be public, protected or private, just like a normal function. To create a slot:

1. Put Q_OBJECT macro in header file right below the opening bracket like this:

class MyClass: public QObject{

Q_OBJECT

2. Declare the slot in class in public slots, protected slots or private slots section:

public slots:void mySlot(int arg1);

3. Define the slot in .cpp just like a regular function:

void MyClass::mySlot(int arg1) {int a = arg1 + 10;qDebug() << "the answer is " << a;

}

Note: Here qDebug() function is used to print the answer in the console, you can think of it as analouge ofprintf().

The only thing left is to connect mySlot() to some signal, so it will be called every time signal is triggered.

3.3. QObject model philosophy 23

Page 28: qtlabs Documentation - Read the Docs

qtlabs Documentation, Release

Signal-slot connetion

Connection between signals and slots is performed using connect(). Normally, you use it like this:

MyClass* obj1 = new MyClass;MyClass* obj2 = new MyClass;QObject::connect(obj1, SIGNAL(mySignal(int)), obj2, SLOT(mySlot(int)));

Note: As mentioned above, you call connect() from any part of the program. Nevertheless, you should addQObject:: before connect() if you try to use it outside of class inherited from QObject, for instance, in main().

Arguments of connect() are:

• sender: pointer to the sender object;

• signal: pointer to the signal function (you can see it is inside the SIGNAL() macro)

• receiver: pointer to the receiver object;

• slot: pointer to the slot function (you can see it is inside the SLOT() macro)

Note: If you call connect() inside a class and want to use it as the receiver or the sender, you can use this pointerinstead

So that is it! Every time mySignal() of obj1 is triggered mySlot() of obj2 is called. Later on, if you want todisconnect these signal and slot you only need to call disconnect function:

After that, obj2 will no longer react on mySignal() of obj1.

Only few more notes about connections left:

1. Signal can be connected to other signals. If so, signal that used a slot will be emitted every time the first signal isemitted.

2. Signal and slot that are connected to each other should have the same number of arguments. The only exception iswhen slot does not have any arguments at all.

Conclusion and exercise

Thus, we have discussed basic principles of Qt. It is a good alternative to classic implementation of connectionbetween component, even though it brings some overheads. QObject is a base class for almost each class in Qt. It isused to create a hyerarchical model, automatic memory management, and for realization of signal-slot model. Signalsand slots help objects to communicate with each other. Signals can be connected to few slots, as well slot can beconnected to few signals. Slot function is called whenever the dedicated signal is triggered.

Exercise

Let’s create this time a image viewer. It will show pics from a specified folder. It should has a label that will showan image and two buttons: “Next” and “Previous”, that will change the current image. Few hints on how to do it,although you can have a better idea of implementation:

1. Create Qt widget application project.

2. Create a class inherited from QWidget.

24 Chapter 3. Lab 1. Qt basics

Page 29: qtlabs Documentation - Read the Docs

qtlabs Documentation, Release

3. Add one QLabel and two QPushButtons as attributes of this class.

Note: You at look previos examples to refresh memories, or check out QPushButton and QLabel documentation tosee a bit more about these classes.

4. Implement a function, that would set up the path for viewer’s directory

Note: Please, check out QString class documentaion. It is a common class used for strings in Qt.

5. Implement slots, that will set next and previos image in the folder as the current pixmap for our label.

Hint: QDir is the class of choice for you. It has a function operator [] which returns the name of a file at theposition specified inside the brackets, for instance:

QDir dir("/home/user");QString fileName= dir[1];

will return the name of the second file in “/home/user directory”

6. Connect signals of your buttons to dedicated slots you have created.

7. Create an instance of your calss in main().

Good luck!

3.4. Conclusion and exercise 25