QT
QT
QT
#qt
Table of Contents
About 1
Remarks 2
Versions 2
Examples 2
Hello World 8
Introduction 13
Remarks 13
Examples 13
Combining Layouts 15
Introduction 19
Examples 19
Build on Windows 19
Examples 20
CMakeLists.txt for Qt 5 20
Examples 22
Introduction 24
Examples 24
Examples 30
Deploying on windows 30
Deploying on Mac 31
Deploying on linux 32
Introduction 33
Examples 33
Remarks 38
Examples 38
Basic Concept 38
Examples 40
Remarks 47
Examples 47
Video Playback in Qt 5 47
Remarks 49
Examples 49
MyCompareFileDialog.h 49
MyCompareFileDialogDialog.cpp 49
MainWindow.h 50
MainWindow.cpp 50
main.cpp 51
mainwindow.ui 51
Examples 53
Examples 55
SUBDIRS example 57
Library example 59
Remarks 61
Examples 61
QObject example 61
qobject_cast 61
Remarks 64
Examples 64
Using a Database on Qt 64
Remarks 71
Examples 71
QStack usage 71
QVector usage 71
QLinkedList usage 72
QList 72
Introduction 75
Examples 75
TCP Client 75
TCP Server 77
Introduction 81
Examples 81
Remarks 82
Examples 82
Simple example 82
Basic Usage 84
Introduction 87
Remarks 87
Examples 87
A Small Example 87
Examples 94
Basic connection and query 94
Remarks 98
Examples 98
QtConcurrent Run 99
Examples 102
Credits 103
About
You can share this PDF with anyone you feel could benefit from it, downloaded the latest version
from: qt
It is an unofficial and free Qt ebook created for educational purposes. All the content is extracted
from Stack Overflow Documentation, which is written by many hardworking individuals at Stack
Overflow. It is neither affiliated with Stack Overflow nor official Qt.
The content is released under Creative Commons BY-SA, and the list of contributors to each
chapter are provided in the credits section at the end of this book. Images may be copyright of
their respective owners unless otherwise specified. All trademarks and registered trademarks are
the property of their respective company owners.
Use the content presented in this book at your own risk; it is not guaranteed to be correct nor
accurate, please send your feedback and corrections to info@zzzprojects.com
https://riptutorial.com/ 1
Chapter 1: Getting started with Qt
Remarks
As official documentation stated, Qt is a cross-platform application development framework for
desktop, embedded and mobile. Supported Platforms include Linux, OS X, Windows, VxWorks,
QNX, Android, iOS, BlackBerry, Sailfish OS and others.
This section provides an overview of what Qt is, and why a developer might want to use it.
It should also mention any large subjects within Qt, and link out to the related topics. Since the
documentation for qt is new, you may need to create initial versions of those related topics.
Versions
Qt 3.0 2001-10-16
Qt 3.3 2004-02-05
Qt 4.1 2005-12-20
Qt 4.8 2011-12-15
Qt 5.0 2012-12-19
Qt 5.6 2016-03-16
Qt 5.7 2016-06-16
Qt 5.8 2017-01-23
Qt 5.9 2017-05-31
Examples
Installation and Setup on Windows and Linux
https://riptutorial.com/ 2
A file with the name qt-unified-linux-x-online.run will be downloaded, then add exec permission
chmod +x qt-unified-linux-x-online.run
Remember to change 'x' for the actual version of the installer. Then run the installer
./qt-unified-linux-x-online.run
https://riptutorial.com/ 3
What you should do now depends on which IDE you're going to use. If you're going to use Qt
Creator, which is included in the installer program, just click on Download Now and run the
executable.
If you're going to use Qt in Visual Studio, normally the Download Now button should also work.
Make sure the file downloaded is called qt-opensource-windows-x86-msvc2015_64-x.x.x.exe or
qt-opensource-windows-x86-msvc2015_32-x.x.x.exe (where x.x.x is the version of Qt, for example
5.7.0). If that's not the case, click on View All Downloads and select one of the first four options
under Windows Host.
If you're going to use Qt in Code::Blocks, click on View All Downloads and select Qt x.x.x for
Windows 32-bit (MinGW x.x.x, 1.2 GB) under Windows Host.
Once you've downloaded the appropriate installer file, run the executable and follow the
instructions below. Note that you need to be an administrator to install Qt. If you're not an
https://riptutorial.com/ 4
administrator, you can find several alternative solutions here.
Once you've downloaded Qt and opened the installer program, the installation procedure is the
same for all operative systems, although the screenshots might look a bit different. The
screenshots provided here are from Linux.
https://riptutorial.com/ 5
Select the library version and the features you want
https://riptutorial.com/ 6
After downloading and the installation is finished, go to the Qt installation directory and launch Qt
Creator or run it directly from the command line.
https://riptutorial.com/ 7
Hello World
In this example, we simply create and show a push button in a window frame on the desktop. The
push button will have the label Hello world!
helloworld.pro
QT += core gui
https://riptutorial.com/ 8
TARGET = helloworld
TEMPLATE = app
SOURCES += main.cpp
• QT is used to indicate what libraries (Qt modules) are being used in this project. Since our
first app is a small GUI, we will need QtCore and QtGui. As Qt5 separate QtWidgets from
QtGui, we need add greaterThan line in order to compile it with Qt5.
• TARGET is the name of the app or the library.
• TEMPLATE describes the type to build. It can be an application (app), a library (lib), or
simply subdirectories (subdirs).
• SOURCES is a list of source code files to be used when building the project.
main.cpp
#include <QApplication>
#include <QPushButton>
return a.exec(); // .exec starts QApplication and related GUI, this line starts 'event
loop'
}
Finally, to run the application, open a command prompt, and enter the directory in which you have
the .cpp file of the program. Type the following shell commands to build the program.
qmake -project
qmake
make
QtCreator is, at the moment, the best tool to create a Qt application. In this example, we will see
how to create a simple Qt application which manage a button and write text.
https://riptutorial.com/ 9
https://riptutorial.com/ 10
which is an awesome class which can convert many thing in many others things. So left add an int
which increase when we push the button.
So the .h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void whenButtonIsClicked();
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
double _smallCounter;
};
#endif // MAINWINDOW_H
The .cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// connect(ui->pushButton, SIGNAL(clicked(bool)), this, SLOT(whenButtonIsClicked()));
_smallCounter = 0.0f;
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::whenButtonIsClicked()
{
ui->label->setText("the button has been clicked !");
}
https://riptutorial.com/ 11
void MainWindow::on_pushButton_clicked()
{
_smallCounter += 0.5f;
ui->label->setText("it's even easier ! " + QVariant(_smallCounter).toString());
}
And now, we can save and run again. Every time you click on the button, it show "it's even easier !
" with the value of _smallCounter. So you should have something like:
This tutorial is done. If you want to learn more about Qt, let's see the other examples and
documentation of Qt on the StackOverflow Documentation or the Qt Documentation
https://riptutorial.com/ 12
Chapter 2: About using layouts, widget
parenting
Introduction
The layouts are a necessary in every Qt application. They manage the object, their position, their
size, how they are resized.
Remarks
From Qt layout documentation:
When you use a layout, you do not need to pass a parent when constructing the child
widgets. The layout will automatically reparent the widgets (using
QWidget::setParent()) so that they are children of the widget on which the layout is
installed.
So do :
or do :
Examples
Basic Horizontal Layout
basic code:
#include <QApplication>
#include <QMainWindow>
#include <QWidget>
#include <QHBoxLayout>
#include <QPushButton>
https://riptutorial.com/ 13
QApplication a(argc, argv);
QMainWindow window;
QWidget *widget = new QWidget(&window);
QHBoxLayout *layout = new QHBoxLayout(widget);
window.setCentralWidget(widget);
widget->setLayout(layout);
window.show();
return a.exec();
}
#include "mainwindow.h"
#include <QApplication>
#include <QMainWindow>
#include <QWidget>
#include <QVBoxLayout>
#include <QPushButton>
QMainWindow window;
QWidget *widget = new QWidget(&window);
QVBoxLayout *layout = new QVBoxLayout(widget);
window.setCentralWidget(widget);
widget->setLayout(layout);
https://riptutorial.com/ 14
layout->addWidget(new QPushButton("layouts are so great !", widget));
window.show();
return a.exec();
}
output:
Combining Layouts
You can combine mulple layout thanks to other QWidgets in your main layout to do more specifics
effects like an information field: for example:
#include <QApplication>
#include <QMainWindow>
#include <QWidget>
#include <QVBoxLayout>
#include <QPushButton>
#include <QLabel>
#include <QLineEdit>
#include <QGroupBox>
#include <QTextEdit>
QMainWindow window;
QWidget *widget = new QWidget(&window);
QVBoxLayout *layout = new QVBoxLayout(widget);
window.setCentralWidget(widget);
widget->setLayout(layout);
layout->addWidget(box);
boxLayout->addWidget(nameWidget);
boxLayout->addWidget(ageWidget);
https://riptutorial.com/ 15
boxLayout->addWidget(addressWidget);
layout->addWidget(validateWidget);
window.show();
return a.exec();
}
will output :
The grid layout is a powerful layout with which you can do an horizontal and vertical layout a once.
example:
#include "mainwindow.h"
#include <QApplication>
https://riptutorial.com/ 16
#include <QMainWindow>
#include <QWidget>
#include <QVBoxLayout>
#include <QPushButton>
#include <QLabel>
#include <QLineEdit>
#include <QGroupBox>
#include <QTextEdit>
QMainWindow window;
QWidget *widget = new QWidget(&window);
QGridLayout *layout = new QGridLayout(widget);
window.setCentralWidget(widget);
widget->setLayout(layout);
boxLayout->addWidget(nameWidget);
boxLayout->addWidget(ageWidget);
boxLayout->addWidget(addressWidget);
window.show();
return a.exec();
}
give :
https://riptutorial.com/ 17
so you can see that the group box is only in the first column and first row as the addWidget was
layout->addWidget(box, 0, 0);
However, if you change it to layout->addWidget(box, 0, 0, 1, 3);, the new 0 and 3 represent how
many line and column you want for your widget so it give :
exactly the same as you created a horizontal and then a vertical layout in a subwidget.
https://riptutorial.com/ 18
Chapter 3: Build QtWebEngine from source
Introduction
Sometimes we need to build QtWebEngine from source for some reason, such as for mp3
support.
Examples
Build on Windows
Requirements
• Windows 10, please set your system locale to English, otherwise there may be errors
• Visual Studio 2013 or 2015
• QtWebEngine 5.7 source code (could be downloaded from here)
• Qt 5.7 install version, install it and add qmake.exe folder to system path
• Python 2, add python.exe folder to system path
• Git, add git.exe folder to system path
• gperf, add gperf.exe folder to system path
• flex-bison, add win_bison.exe folder to system path, and rename it to bison.exe
Note: I didn't test for Visual Studio versions, all Qt versions.. Let's just take an example
here, other versions should be about the same.
Steps to build
Note: Mp3 is not supported by QtWebEngine by default, due to license issue. Please
make sure to get a license for the codec you added.
https://riptutorial.com/ 19
Chapter 4: CMakeLists.txt for your Qt project
Examples
CMakeLists.txt for Qt 5
cmake_minimum_required(VERSION 2.8.11)
project(myproject)
set(CMAKE_AUTOMOC ON)
add_executable(${PROJECT_NAME}
main.cpp
)
target_link_libraries(${PROJECT_NAME}
Qt5::Core
)
cmake_minimum_required is called to set minimum required version for CMake. The minimum
required version for this example to work is 2.8.11 -- previous versions of CMake need additional
code for a target to use Qt.
find_package is called to search an installation of Qt5 with a given version -- 5.7.0 in the example --
and wanted components -- Core module in the example. For a list of available modules, see Qt
Documentation. Qt5 is marked as REQUIRED in this project. The path to the installation can be hinted
by setting the variable Qt5_DIR.
AUTOMOC is a boolean specifying whether CMake will handle the Qt moc preprocessor automatically,
i.e. without having to use the QT5_WRAP_CPP() macro.
• AUTOUIC:
a boolean specifying whether CMake will handle the Qt uic code generator
automatically, i.e. without having to use the QT5_WRAP_UI() macro.
• AUTORCC:
a boolean specifying whether CMake will handle the Qt rcc code generator
automatically, i.e. without having to use the QT5_ADD_RESOURCES() macro.
add_executable is called to create an executable target from the given source files. The target is
then linked to the listed Qt's modules with the command target_link_libraries. From CMake
2.8.11, target_link_libraries with Qt's imported targets handles linker parameters, as well as
include directories and compiler options.
https://riptutorial.com/ 20
Read CMakeLists.txt for your Qt project online: https://riptutorial.com/qt/topic/1991/cmakelists-txt-
for-your-qt-project
https://riptutorial.com/ 21
Chapter 5: Common Pitfalls
Examples
Using Qt:DirectConnection when receiver object doesn't receive signal
Some times you see a signal is emitted in sender thread but connected slot doesn't called (in other
words it doesn't receive signal), you have asked about it and finaly got that the connection type
Qt::DirectConnection would fix it, so the problem found and everything is ok.
But generaly this is bad idea to use Qt:DirectConnection until you really know what is this and
there is no other way. Lets explain it more, Each thread created by Qt (including main thread and
new threads created by QThread) have Event loop, the event loop is responsible for receiving
signals and call aproporiate slots in its thread. Generaly executing a blocking operation inside an
slot is bad practice, because it blocks the event loop of that threads so no other slots would be
called.
If you block an event loop (by making very time consuming or blocking operation) you will not
receive events on that thread until the event loop will be unblocked. If the blocking operation,
blocks the event loop forever (such as busy while), the slots could never be called.
In this situation you may set the connection type in connect to Qt::DirectConnection, now the slots
will be called even the event loop is blocked. so how this could make broke everything? In
Qt::DirectConnection Slots will be called in emiter threads, and not receiver threads and it can
broke data synchronizations and ran into other problems. So never use Qt::DirectConnection
unless you know what are you doing. If your problem will be solved by using Qt::DirectConnection,
you have to carefull and look at your code and finding out why your event loop is blocked. Its not a
good idea to block the event loop and its not recomended in Qt.
Here is small example which shows the problem, as you can see the nonBlockingSlot would be
called even the blockingSlot blocked event loop with while(1) which indicates bad coding
https://riptutorial.com/ 22
}
};
TestReceiver TestReceiverInstance;
TestSender testSenderInstance(&TestReceiverInstance);
QThread receiverThread;
TestReceiverInstance.moveToThread(&receiverThread);
receiverThread.start();
return a.exec();
}
https://riptutorial.com/ 23
Chapter 6: Communication between QML and
C++
Introduction
We may use QML to build hybrid applications, since it's much more easier than C++. So we
should know how they communicate with each other.
Examples
Call C++ in QML
At C++ side, imagine we have a class named QmlCppBridge, it implements a method called
printHello().
We want to use it in QML side. We should register the class by calling qmlRegisterType():
// Register C++ class as a QML module, 1 & 0 are the major and minor version of the QML module
qmlRegisterType<QmlCppBridge>("QmlCppBridge", 1, 0, "QmlCppBridge");
import QmlCppBridge 1.0 // Import this module, so we can use it in our QML script
QmlCppBridge {
id: bridge
}
bridge.printHello();
QQmlApplicationEngine engine;
QQmlContext *context = engine.rootContext();
https://riptutorial.com/ 24
// Inject C++ class to QML
context->setContextProperty(QStringLiteral("qmlCppBridge"), new QmlCppBridge(&engine));
At QML side:
Note: This example is based on Qt 5.7. Not sure if it fits earlier Qt versions.
To call the QML classes in C++, you need to set the objectName property.
In your Qml:
Button {
objectName: "buttonTest"
}
Then, in your C++, you can get the object with QObject.FindChild<QObject*>(QString)
Like that:
QQmlApplicationEngine engine;
QQmlComponent component(&engine, QUrl(QLatin1String("qrc:/main.qml")));
Now you have your QML object in your C++. But that could seems useless since we cannot really
get the components of the object.
However, we can use it to send signals between the QML and the C++. To do that, you need to
add a signal in your QML file like that: signal buttonClicked(string str). Once you create this, you
need to emit the signal. For example:
Button {
id: buttonTest
objectName: "buttonTest"
https://riptutorial.com/ 25
}
}
Here we have our qml button. When we click on it, it goes to the onClicked method (a base
method for buttons which is called when you press the button). Then we use the id of the button
and the name of the signal to emit the signal.
And in our cpp, we need to connect the signal with a slot. like that:
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlComponent>
#include "ButtonManager.h"
QQmlApplicationEngine engine;
QQmlComponent component(&engine, QUrl(QLatin1String("qrc:/main.qml")));
ButtonManager buttonManager(mainPage);
QObject::connect(item, SIGNAL(clickedButton(QString)), &buttonManager,
SLOT(onButtonClicked(QString)));
return app.exec();
}
As you can see, we get our qml button with findChild as before and we connect the signal to a
Button manager which is a class created and who look like that. ButtonManager.h
#ifndef BUTTONMANAGER_H
#define BUTTONMANAGER_H
#include <QObject>
#endif // BUTTONMANAGER_H
ButtonManager.cpp
https://riptutorial.com/ 26
#include "ButtonManager.h"
#include <QDebug>
ButtonManager::ButtonManager(QObject *parent)
: QObject(parent)
{
So when the signal will be received, it will call the method onButtonClicked which will write "button:
clicked !"
output:
https://riptutorial.com/ 27
https://riptutorial.com/ 28
https://riptutorial.com/qt/topic/8735/communication-between-qml-and-cplusplus
https://riptutorial.com/ 29
Chapter 7: Deploying Qt applications
Examples
Deploying on windows
Qt provides a deployment tool for Windows: windeployqt. The tool inspects a Qt application
executable for its dependecies to Qt modules and creates a deployment directory with the
necessary Qt files to run the inspected executable. A possible script may look like:
set PATH=%PATH%;<qt_install_prefix>/bin
windeployqt --dir /path/to/deployment/dir /path/to/qt/application.exe
The set command is called to add Qt's bin directory to the PATH environment variable. windeployqt
is then called:
• The path to the deployment directory is given an optional argument given with the parameter
--dir (default is the path where windeployqt is called).
• The path to the executable to be inspected is given as last argument.
NOTE:
If you are using pre-compiled Qt5.7.0 with vs2013 on Windows (not sure if all versions has this
issue), there is a chance, that you need to manually copy <QTDIR>\5.7\msvc2015\qml to your bin
directory of your program. Otherwise the program will auto quit after start.
It is possible to run windeployqt and macdeployqt from CMake, but first the path to the executables
must be found:
# Retrieve the absolute path to qmake and then use that path to find
# the binaries
get_target_property(_qmake_executable Qt5::qmake IMPORTED_LOCATION)
get_filename_component(_qt_bin_dir "${_qmake_executable}" DIRECTORY)
find_program(WINDEPLOYQT_EXECUTABLE windeployqt HINTS "${_qt_bin_dir}")
find_program(MACDEPLOYQT_EXECUTABLE macdeployqt HINTS "${_qt_bin_dir}")
In order for windeployqt to find the Qt libraries in their installed location, the folder must be added to
%PATH%. To do this for a target named myapp after being built:
https://riptutorial.com/ 30
"$<TARGET_FILE:myapp>"
COMMENT "Running windeployqt..."
)
Deploying on Mac
The Mac deployment tool can be found in QTDIR/bin/macdeployqt. It is designed to automate the
process of creating a deployable application bundle that contains the Qt libraries as private
frameworks.
The mac deployment tool also deploys the Qt plugins, according to the following rules (unless -no-
plugins option is used):
To include a 3rd party library in the application bundle, copy the library into the bundle manually,
after the bundle is created.
The app file will now contain all the Qt Libraries used as private frameworks.
Option Description
https://riptutorial.com/ 31
Option Description
-use-debug-libs Deploy with debug versions of frameworks and plugins (implies -no-strip)
-executable= Let the given executable also use the deployed frameworks
Deploying on linux
There is a a deployment tool for linux on GitHub. While not perfect, it is linked to from the Qt wiki.
It's based conceptually on the Qt Mac Deployment Tool and functions similarly by providing an
AppImage.
Given that a desktop file should be provided with an AppImage, linuxdeployqt can use that to
determine the parameters of the build.
linuxdeployqt ./path/to/appdir/usr/share/application_name.desktop
Where the desktop file specifies the executable to be run (with EXEC=), the name of the application,
and an icon.
https://riptutorial.com/ 32
Chapter 8: Header on QListView
Introduction
The QListView widget is part of the Model/View programming mechanisms of Qt. Basically, it
allows to display items stored in a Model under the form of a list. In this topic we will not get deep
into the Model/View mechanisms of Qt, but rather focus on the graphical aspect of one View
widget: the QListView, and especially how to add a header on top of this object through the use of
the QPaintEvent object.
Examples
Custom QListView declaration
/*!
* \class MainMenuListView
* \brief The MainMenuListView class is a QListView with a header displayed
* on top.
*/
class MainMenuListView : public QListView
{
Q_OBJECT
/*!
* \class Header
* \brief The header class is a nested class used to display the header of a
* QListView. On each instance of the MainMenuListView, a header will
* be displayed.
*/
class Header : public QWidget
{
public:
/*!
* \brief Constructor used to defined the parent/child relation
* between the Header and the QListView.
* \param parent Parent of the widget.
*/
Header(MainMenuListView* parent);
/*!
* \brief Overridden method which allows to get the recommended size
* for the Header object.
* \return The recommended size for the Header widget.
*/
QSize sizeHint() const;
protected:
/*!
* \brief Overridden paint event which will allow us to design the
* Header widget area and draw some text.
* \param event Paint event.
*/
void paintEvent(QPaintEvent* event);
https://riptutorial.com/ 33
private:
MainMenuListView* menu; /*!< The parent of the Header. */
};
public:
/*!
* \brief Constructor allowing to instanciate the customized QListView.
* \param parent Parent widget.
* \param header Text which has to be displayed in the header
* (Header by default)
*/
MainMenuListView(QWidget* parent = nullptr, const QString& header = QString("Header"));
/*!
* \brief Catches the Header paint event and draws the header with
* the specified text in the constructor.
* \param event Header paint event.
*/
void headerAreaPaintEvent(QPaintEvent* event);
/*!
* \brief Gets the width of the List widget.
* This value will also determine the width of the Header.
* \return The width of the custom QListView.
*/
int headerAreaWidth();
protected:
/*!
* \brief Overridden method which allows to resize the Header.
* \param event Resize event.
*/
void resizeEvent(QResizeEvent* event);
private:
QWidget* headerArea; /*!< Header widget. */
QString headerText; /*!< Header title. */
};
https://riptutorial.com/ 34
// Really important. The view port margins define where the content
// of the widget begins.
setViewportMargins(0, fontMetrics().height(), 0, 0);
}
int MainMenuListView::headerAreaWidth()
{
return width();
}
class MainMenuListView;
public:
MainWindow(QWidget* parent = 0);
~MainWindow();
private:
MainMenuListView* menuA;
MainMenuListView* menuB;
MainMenuListView* menuC;
};
https://riptutorial.com/ 35
QHBoxLayout* hbox = new QHBoxLayout();
w->setLayout(hbox);
setCentralWidget(w);
MainWindow::~MainWindow() {}
https://riptutorial.com/ 36
As you can seen above, it can be useful for creating stacked menus. Note that this sample is
trivial. The two widgets have the same size constraints.
https://riptutorial.com/ 37
Chapter 9: Implicit sharing
Remarks
STL style iterators on Qt Container can have some negative side effect due to the implicit-sharing.
It is advised to avoid copying a Qt container while you have iterators active on them.
auto iter = a.begin(); //iter also points to the same memory a and b do
a[4] = 1; //a creates a new copy and points to different memory.
//Warning 1: b and iter point sill to the same even if iter was "a.begin()"
Examples
Basic Concept
Several Qt Objects and Containers use a concept calles implicit sharing, which can also be
refered to as copy-on-write.
Implicit sharing means that the classes who use this concept share the same data on initialization.
This is a simplified model of a QString. Internally it has a memory block, with the actual string data
and and a reference counter.
QString s2 = s1;
https://riptutorial.com/ 38
If we now copy this QString both objects will internally point to the same content, thus avoiding
unnecessary copy operations. Note how the reference count also got upped. So in case the first
string gets deleted the shared-data still knows it is referenced by another QString.
Now when the QString is actually modified the object "detaches" itself from the memory block,
copying it's content and modifies the content.
https://riptutorial.com/ 39
Chapter 10: Model/View
Examples
A Simple Read-only Table to View Data from a Model
This is a simple example to display read-only data that is tabular in nature using Qt's Model/View
Framework. Specifically, the Qt Objects QAbstractTableModel (sub-classed in this example) and
QTableView are used.
Implementations of the methods rowCount(), columnCount(), data() and headerData() are required
to give the QTableView object a means to obtain information about the data contained in the
QAbstractTableModel object.
The method populateData() was added to this example to provide a means to populate the
QAbstractTableModel object with data from some arbitrary source.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QAbstractTableModel>
namespace Ui {
class MainWindow;
}
public:
TestModel(QObject *parent = 0);
private:
QList<QString> tm_contact_name;
QList<QString> tm_contact_phone;
};
https://riptutorial.com/ 40
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QList<QString> contactNames;
QList<QString> contactPhoneNums;
// Create model:
TestModel *PhoneBookModel = new TestModel(this);
MainWindow::~MainWindow()
{
delete ui;
}
https://riptutorial.com/ 41
tm_contact_name.clear();
tm_contact_name = contactName;
tm_contact_phone.clear();
tm_contact_phone = contactPhone;
return;
}
Using Qt Creator/Design, place a Table View object, named tableView in this example, in the main
window:
https://riptutorial.com/ 42
The resulting program displays as:
QModelIndex does not actually know about it's parent/child indexes, it only contains a row, a
column and a pointer, and it is the models responsibility to use this data to provide information an
index's relations. The model therefore needs to do a lot of conversions from the void* stored inside
the QModelIndex to an internal data type and back.
TreeModel.h:
#pragma once
#include <QAbstractItemModel>
https://riptutorial.com/ 43
{
Q_OBJECT
public:
explicit TreeModel(QObject *parent = nullptr);
private:
struct Item
{
~Item();
TreeModel.cpp:
#include "TreeModel.h"
TreeModel::Item::~Item()
{
qDeleteAll(children);
}
int TreeModel::Item::rowInParent() const
{
if (parent) {
return parent->children.indexOf(const_cast<Item *>(this));
} else {
return 0;
}
}
TreeModel::TreeModel(QObject *parent)
https://riptutorial.com/ 44
: QAbstractItemModel(parent), m_root(new Item) {}
// We can now simply look up the item we want given the parent and the row
Item *childItem = parentItem->children.at(row);
https://riptutorial.com/ 45
}
Item *item = static_cast<Item *>(index.internalPointer());
return item->values.at(index.column());
}
bool TreeModel::setData(const QModelIndex &index, const QVariant &value,
const int role)
{
// As in data there will usually be more stuff here, like type conversion to
// QVariant, checking values for validity etc.
if (!index.isValid() || role != Qt::EditRole) {
return false;
}
Item *item = static_cast<Item *>(index.internalPointer());
item->values[index.column()] = value;
emit dataChanged(index, index, QVector<int>() << role);
return true;
}
Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
{
if (index.isValid()) {
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
} else {
return Qt::NoItemFlags;
}
}
https://riptutorial.com/ 46
Chapter 11: Multimedia
Remarks
Qt Multimedia is a module providing handling of multimedia (audio, video) and also camera and
radio functionality.
However, the supported files of QMediaPlayer depends on the platform. Indeed, on windows,
QMediaPlayer uses DirectShow, on Linux, it uses GStreamer. So depending on the platform some
files may work on Linux but not on Windows or the opposite.
Examples
Video Playback in Qt 5
In .pro file of your application you will need the following lines:
QT += multimedia multimediawidgets
#include <QtMultimedia/QMediaPlayer>
#include <QtMultimedia/QMediaPlaylist>
#include <QtMultimediaWidgets/QVideoWidget>
QMediaPlayer *player;
QVideoWidget *videoWidget;
QMediaPlaylist *playlist;
videoWidget->show();
player->play();
That's all - after launching the application (if necessary codecs are installed in the system), video
file playback will be started.
The same way you can play video from URL in Internet, not just local file.
https://riptutorial.com/ 47
As this is an audio, we don't need a QVideoWidget. So we can do:
in the .h:
QMediaPlayer *_player;
this will open a dialog where you can choose your music and it will play it.
https://riptutorial.com/ 48
Chapter 12: QDialogs
Remarks
The QDialog class is the base class of dialog windows. A dialog window is a top-level window
mostly used for short-term tasks and brief communications with the user. QDialogs may be modal
or modeless.
Note that QDialog (and any other widget that has type Qt::Dialog) uses the parent widget slightly
differently from other classes in Qt. A dialog is always a top-level widget, but if it has a parent,
its default location is centered on top of the parent's top-level widget (if it is not top-level
itself). It will also share the parent's taskbar entry.
A modal dialog is a dialog that blocks input to other visible windows in the same application.
Dialogs that are used to request a file name from the user or that are used to set application
preferences are usually modal. Dialogs can be application modal (the default) or window modal.
The most common way to display a modal dialog is to call its exec() function. When the user
closes the dialog, exec() will provide a useful return value.
A modeless dialog is a dialog that operates independently of other windows in the same
application. Modeless dialogs are displayed using show(), which returns control to the caller
immediately.
Examples
MyCompareFileDialog.h
#ifndef MYCOMPAREFILEDIALOG_H
#define MYCOMPAREFILEDIALOG_H
#include <QtWidgets/QDialog>
public:
MyCompareFileDialog(QWidget *parent = 0);
~MyCompareFileDialog();
};
#endif // MYCOMPAREFILEDIALOG_H
MyCompareFileDialogDialog.cpp
#include "MyCompareFileDialog.h"
https://riptutorial.com/ 49
#include <QLabel>
MyCompareFileDialog::MyCompareFileDialog(QWidget *parent)
: QDialog(parent)
{
setWindowTitle("Compare Files");
setWindowFlags(Qt::Dialog);
setWindowModality(Qt::WindowModal);
resize(300, 100);
QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
setSizePolicy(sizePolicy);
setMinimumSize(QSize(300, 100));
setMaximumSize(QSize(300, 100));
MyCompareFileDialog::~MyCompareFileDialog()
{ }
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MyCompareFileDialog;
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
MyCompareFileDialog* myDialog;
};
#endif // MAINWINDOW_H
MainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "mycomparefiledialog.h"
MainWindow::MainWindow(QWidget *parent) :
https://riptutorial.com/ 50
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->pushButton,SIGNAL(clicked()),myDialog,SLOT(exec()));
}
MainWindow::~MainWindow()
{
delete ui;
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
return a.exec();
}
mainwindow.ui
https://riptutorial.com/ 51
<string>Show My Dialog</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
https://riptutorial.com/ 52
Chapter 13: QGraphics
Examples
Pan, zoom, and rotate with QGraphicsView
can be used to organize complicated scenes of visual objects into a framework that
QGraphics
makes them easier to handle.
There are three major types of objects used in this framework QGraphicsView, QGraphicsScene,
and QGraphicsItems. QGraphicsItems are the basic visual items that exist in the scene.
There are many types that are pre-built and can be used such as Ellipses, Lines, Paths, Pixmaps,
Polygons, Rectangles, and Text.
You can also make your own items by inheriting QGraphicsItem. These items are then put into a
QGraphicsScene which is basically the world you are planning to look at. The items can move within
the scene which is like having them move in the world you are looking at. The items positioning
and orientation is handled by transformation matrices called QTransforms. Qt has nice functions
built in so you usually do not need to work with the QTransforms directly, instead you call functions
such as rotate or scale which create the proper transforms for you. The scene is then viewed by
the perspective defined in the QGraphicsView (again with QTransforms), which is the piece you would
put into a widget in you UI.
In the following example there is a very simple scene with just one item (a pixmap), which is put
into a scene and displayed in a view. By turning on the DragMode flag the scene can be panned
around with the mouse and by using the scale and rotate functions it can be scaled in and out with
the scroll on the mouse and rotated with the arrow keys.
If you would like to run this example create a instance of View that will be displayed and create a
resource file with the prefix /images containing a image my_image.png.
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>
#include <QWheelEvent>
#include <QKeyEvent>
https://riptutorial.com/ 53
QGraphicsScene *scene = new QGraphicsScene();
scene->addItem(pixmapItem);
setScene(scene);
}
protected Q_SLOTS:
void wheelEvent(QWheelEvent *event)
{
if(event->delta() > 0)
scale(1.25, 1.25);
else
scale(0.8, 0.8);
}
https://riptutorial.com/ 54
Chapter 14: qmake
Examples
Default "pro" file.
qmake is a build automation tool, which is shipped with Qt framework. It does similar job to tools
such as CMake or GNU Autotools, but it is designed to be used specifically with Qt. As such it is
well integrated with Qt ecosystem, notably Qt Creator IDE.
If you start Qt Creator and select File -> New File or Project -> Application -> Qt Widgets
application, Qt Creator will generate a project skeleton for you along with a "pro" file. The "pro" file
is processed by qmake in order to generate files, which are in turn processed by underlying build
systems (for example GNU Make or nmake).
If you named your project "myapp", then "myapp.pro" file will appear. Here's how such default file
looks like, with comments, that describe each qmake variable, added.
# Tells build system that project uses Qt Core and Qt GUI modules.
QT += core gui
# Prior to Qt 5 widgets were part of Qt GUI module. In Qt 5 we need to add Qt Widgets module.
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
# List of source files (note: Qt Creator will take care about this list, you don't need to
update is manually).
SOURCES += main.cpp\
mainwindow.cpp
# List of header files (note: Qt Creator will take care about this list).
HEADERS += mainwindow.h
# List of "ui" files for a tool called Qt Designer, which is embedded into Qt Creator in newer
versions of IDE (note: Qt Creator will take care about this list).
FORMS += mainwindow.ui
If you like to organize your project by keeping source files in different subdirectories, you should
know that during a build qmake will not preserve this directory structure and it will keep all the ".o"
files in a single build directory. This can be a problem if you had conflicting file names in different
directories like following.
https://riptutorial.com/ 55
src/file1.cpp
src/plugin/file1.cpp
Now qmake will decide to create two "file1.o" files in a build directory, causing one of them to be
overwritten by another. The buld will fail. To prevent this you can add CONFIG +=
object_parallel_to_source configuration option to your "pro" file. This will tell qmake to generate
build files that preserve your source directory structure. This way your build directory will reflect
source directory structure and object files will be created in separate subdirectories.
src/file1.o
src/plugin/file1.o
Complete example.
QT += core
TARGET = myapp
TEMPLATE = app
CONFIG += object_parallel_to_source
SOURCES += src/file1.cpp \
src/plugin/file1.cpp
HEADERS += src/plugin/file1.h
Window.h
#include <QWidget>
main.cpp
#include <QApplication>
#include "Window.h"
int main()
{
QApplication app;
Window window;
window.show();
return app.exec();
}
https://riptutorial.com/ 56
example.pro
Command Line
SUBDIRS example
The SUBDIRS ability of qmake can be used to compile a set of libraries, each of which depend on
another. The example below is slightly convoluted to show variations with the SUBDIRS ability.
Directory Structure
Some of the following files will be omitted in the interest of brevity. They can be assumed to be the
format as non-subdir examples.
project_dir/
-project.pro
-common.pri
-build.pro
-main.cpp
-logic/
----logic.pro
----some logic files
-gui/
----gui.pro
----gui files
project.pro
This is the main file that enables the example. This is also the file that would be called with qmake
on the command line (see below).
TEMPLATE = subdirs # This changes to the subdirs function. You can't combine
# compiling code and the subdirs function in the same .pro
# file.
# By default, you assign a directory to the SUBDIRS variable, and qmake looks
https://riptutorial.com/ 57
# inside that directory for a <dirname>.pro file.
SUBDIRS = logic
# You can append as many items as desired. You can also specify the .pro file
# directly if need be.
SUBDIRS += gui/gui.pro
# You can also create a target that isn't a subdirectory, or that refers to a
# different file(*).
SUBDIRS += build
build.file = build.pro # This specifies the .pro file to use
# You can also use this to specify dependencies. In this case, we don't want
# the build target to run until after the logic and gui targets are complete.
build.depends = logic gui/gui.pro
(*) See The reference documentation for the other options for a subdirs target.
common.pri
TEMPLATE = lib
logic/logic.pro
HEADERS += logic.h
SOURCES += logic.cpp
gui/gui.pro
! include( ../common.pri ) {
error( "Couldn't find the common.pri file!" )
}
FORMS += gui.ui
HEADERS += gui.h
SOURCES += gui.cpp
https://riptutorial.com/ 58
# TARGET = target
build.pro
TEMPLATE = app
SOURCES += main.cpp
Command Line
Library example
A simple example to make a library (rather than an executable, which is the default). TEMPLATE
variable specifies type of the project you are making. lib option allows makefile to build a library.
library.pro
HEADERS += library.h
SOURCES += library.cpp
TEMPLATE = lib
# By default, qmake will make a shared library. Uncomment to make the library
# static.
# CONFIG += staticlib
When you are building a library, you can add options dll (default), staticlib or plugin to CONFIG.
If you have a directory with existing source files, you can use qmake with the -project-option to
create a project file.
• main.cpp
• foo.h
• foo.cpp
https://riptutorial.com/ 59
• bar.h
• bar.cpp
• subdir/foobar.h
• subdir/foobar.cpp
Then by calling
qmake -project
######################################################################
# Automatically generated by qmake (3.0) Mi. Sep. 7 23:36:56 2016
######################################################################
TEMPLATE = app
TARGET = MyProgram
INCLUDEPATH += .
# Input
HEADERS += bar.h foo.h subdir/foobar.h
SOURCES += bar.cpp foo.cpp main.cpp subdir/foobar.cpp
https://riptutorial.com/ 60
Chapter 15: QObject
Remarks
QObject class is the base class for all Qt objects.
Examples
QObject example
Q_OBJECT macro appears in private section of a class. Q_OBJECT requires the class to be subclass of
QObject. This macro is necessary for the class to declare its signals/slots and to use Qt meta-
object system.
If Meta Object Compiler (MOC) finds class with Q_OBJECT, it processes it and generates C++ source
file containing meta object source code.
#include <QObject>
public:
public slots:
void setNumber(double number);
signals:
void numberChanged(double number);
private:
}
qobject_cast
T qobject_cast(QObject *object)
A functionality which is added by deriving from QObject and using the Q_OBJECT macro is the ability
to use the qobject_cast.
Example:
https://riptutorial.com/ 61
};
To check whether obj is a myObject-type and to cast it to such in C++ you can generally use a
dynamic_cast. This is dependent on having RTTI enabled during compilation.
The Q_OBJECT macro on the other hands generates the conversion-checks and code which can
be used in the qobject_cast.
myObject* my = qobject_cast<myObject*>(obj);
if(!myObject)
{
//wrong type
}
This is not reliant of RTTI. And also allows you to cast across dynamic library boundaries (via Qt
interfaces/plugins).
QObjects come with their own alternative lifetime concept compared to native C++'s raw,unique or
shared pointers.
The simplest way to declare this relationship is by passing the parent object in the constructor. As
an lternative you can manually set the parent of a QObject by calling setParent. This is the only
direction to declare this relationship. You cannot add a child to a parents class but only the other
way round.
QObject parent;
QObject child* = new QObject(&parent);
When parent now gets deleted in stack-unwind child will also be deleted.
When we delete a QObject it will "unregister" itself form the parent object;
QObject parent;
QObject child* = new QObject(&parent);
delete child; //this causes no problem.
QObject parent;
QObject child(&parent);
child will get deleted before parent during stack-unwind and unregister itself from it's parent.
Note: You can manually call setParent with a reverse order of declaration which will break the
https://riptutorial.com/ 62
automatic destruction.
https://riptutorial.com/ 63
Chapter 16: Qt - Dealing with Databases
Remarks
• You will need the Qt SQL plugin corresponding to the type given to QSqlDatabase::addDatabase
• If you don't have the required SQL plugin, Qt will warn you that it can't find the requested
driver
• If you don't have the required SQL plugin you will have to compile them from the Qt source
Examples
Using a Database on Qt
CONFIG += sql
in MainWindow.h we write :
#include <QMainWindow>
#include <QSql>
#include <QDebug>
namespace Ui
{
class MainWindow;
}
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
private:
Ui::MainWindow *ui;
QSqlDatabase db;
};
Now in MainWindow.cpp :
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
https://riptutorial.com/ 64
{
ui->setupUi(this);
MainWindow::~MainWindow()
{
delete ui;
}
in MainWindow.h we write :
#include <QMainWindow>
#include <QSql>
#include <QDebug>
namespace Ui
{
class MainWindow;
}
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
private:
Ui::MainWindow *ui;
QSqlDatabase db;
};
https://riptutorial.com/ 65
Now 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;
}
in MainWindow.h we write :
#include <QMainWindow>
#include <QSql>
#include <QDebug>
namespace Ui
{
class MainWindow;
}
https://riptutorial.com/ 66
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
private:
Ui::MainWindow *ui;
QSqlDatabase db;
};
Now 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()
{
https://riptutorial.com/ 67
delete ui;
}
in MainWindow.h we write :
#include <QMainWindow>
#include <QSql>
#include <QDebug>
namespace Ui
{
class MainWindow;
}
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
private:
Ui::MainWindow *ui;
QSqlDatabase db;
};
Now in MainWindow.cpp :
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
if (!query.exec("CREATE TABLE employees (ID INTEGER, name TEXT, phone TEXT, address
TEXT)"))
https://riptutorial.com/ 68
{
qDebug() << "Can't create table!";
return;
}
if (!query.exec("INSERT INTO employees (ID, name, phone, address) VALUES (201, 'Bob',
'5555-5555', 'Antarctica')"))
{
qDebug() << "Can't insert record!";
return;
}
MainWindow::~MainWindow()
{
delete ui;
}
If we want to remove some database connection from the list of database connections. we need to
use QSqlDatabase::removeDatabase(),however it's a static function and the way it work is a little
wired.
// WRONG WAY
QSqlDatabase db = QSqlDatabase::database("sales");
QSqlQuery query("SELECT NAME, DOB FROM EMPLOYEES", db);
QSqlDatabase::removeDatabase("sales"); // will output a warning
{
QSqlDatabase db = QSqlDatabase::database("sales");
QSqlQuery query("SELECT NAME, DOB FROM EMPLOYEES", db);
}
// Both "db" and "query" are destroyed because they are out of scope
QSqlDatabase::removeDatabase("sales"); // correct
https://riptutorial.com/ 69
databases
https://riptutorial.com/ 70
Chapter 17: Qt Container Classes
Remarks
Qt provides its own template container classes. They are all implicitly shared. They provide two
kinds of iterators (Java style and STL style.)
Examples
QStack usage
QStack<T> is a template Qt class providing stack. Its analogue in STL is std::stack. It is last in, first
out structure (LIFO).
QStack<QString> stack;
stack.push("First");
stack.push("Second");
stack.push("Third");
while (!stack.isEmpty())
{
cout << stack.pop() << endl;
}
QStack inherits from QVector so its implementation is quite different from STL. In STL std::stack is
implemented as a wrapper to type passed as a template argument (deque by default). Still main
operations are the same for QStack and for std::stack.
QVector usage
QVector<T> provides dynamic array template class. It provides better performance in most cases
than QList<T> so it should be first choice.
QVector<int> vect;
vect << 1 << 2 << 3;
QVector<QString> stringsVector;
https://riptutorial.com/ 71
stringsVector.append("First");
stringsVector.append("Second");
v[i] or at[i]
Make sure that i is valid position, even at(i) doesn't make a check, this is a difference from
std::vector.
QLinkedList usage
In Qt you should use QLinkedList in case you need to implement linked list.
It is fast to append, prepend, insert elements into QLinkedList - O(1), but index lookup is slower
than in QList or QVector - O(n). This is normal taking into attention you have to iterate through
nodes to find something in linked list.
Just to insert some elements into QLinkedList you can use operator <<():
QLinkedList<QString> list;
list << "string1" << "string2" << "string3";
To insert elements in the middle of QLinkedList or modify all or some of its elements you can use
Java style or STL style iterators. Here is a simple example how we multiply all the elements of
QLinkedList by 2:
QList
The QList class is a template class that provides lists. It stores items in a list that provides fast
index-based access and index-based insertions and removals.
To insert items into the list, you can use operator<<(), insert(), append() or prepend(). For example:
operator<<()
QList<QString> list;
list << "one" << "two" << "three";
insert()
https://riptutorial.com/ 72
QList<QString> list;
list << "alpha" << "beta" << "delta";
list.insert(2, "gamma");
append()
QList<QString> list;
list.append("one");
list.append("two");
list.append("three");
prepend()
QList<QString> list;
list.prepend("one");
list.prepend("two");
list.prepend("three");
To access the item at a particular index position, you can use operator[]() or at(). at() may be
faster than operator[](), it never causes deep copy of container and should work in constant-time.
Neither of them does argument-check. Examples:
if (list[0] == "mystring")
cout << "mystring found" << endl;
Or
if (list.at(i) == "mystring")
cout << "mystring found at position " << i << endl;
To remove items, there are functions such as removeAt(), takeAt(), takeFirst(), takeLast(),
removeFirst(), removeLast(), or removeOne(). Examples:
takeFirst()
removeOne()
To find all occurrences of a particular value in a list, you can use indexOf() or lastIndexOf().
Example:
indexOf()
https://riptutorial.com/ 73
int i = list.indexOf("mystring");
if (i != -1)
cout << "First occurrence of mystring is at position " << i << endl;
https://riptutorial.com/ 74
Chapter 18: Qt Network
Introduction
Qt Network provide tools to easily use many network protocols in your application.
Examples
TCP Client
To create a TCP connection in Qt, we will use QTcpSocket. First, we need to connect with
connectToHost.
Then, if we need to read datas from the server, we need to connect the signal readyRead with a
slot. Like that:
void MainWindow::onReadyRead()
{
QByteArray datas = _socket.readAll();
qDebug() << datas;
}
_socket.write(QByteArray("ok !\n"));
main.cpp:
#include "mainwindow.h"
#include <QApplication>
return a.exec();
}
https://riptutorial.com/ 75
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTcpSocket>
namespace Ui {
class MainWindow;
}
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void onReadyRead();
private:
Ui::MainWindow *ui;
QTcpSocket _socket;
};
#endif // MAINWINDOW_H
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QHostAddress>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
_socket(this)
{
ui->setupUi(this);
_socket.connectToHost(QHostAddress("127.0.0.1"), 4242);
connect(&_socket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::onReadyRead()
{
QByteArray datas = _socket.readAll();
qDebug() << datas;
_socket.write(QByteArray("ok !\n"));
}
https://riptutorial.com/ 76
mainwindow.ui: (empty here)
TCP Server
Create a TCP server in Qt is also very easy, indeed, the class QTcpServer already provide all we
need to do the server.
First, we need to listen to any ip, a random port and do something when a client is connected. like
that:
_server.listen(QHostAddress::Any, 4242);
connect(&_server, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
Then, When here is a new connection, we can add it to the client list and prepare to read/write on
the socket. Like that:
https://riptutorial.com/ 77
QTcpSocket *clientSocket = _server.nextPendingConnection();
connect(clientSocket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
connect(clientSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this,
SLOT(onSocketStateChanged(QAbstractSocket::SocketState)));
_sockets.push_back(clientSocket);
The stateChanged(QAbstractSocket::SocketState) allow us to remove the socket to our list when the
client is disconnected.
main.cpp:
#include "mainwindow.h"
#include <QApplication>
return a.exec();
}
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
namespace Ui {
class MainWindow;
}
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void onNewConnection();
void onSocketStateChanged(QAbstractSocket::SocketState socketState);
void onReadyRead();
private:
Ui::MainWindow *ui;
QTcpServer _server;
QList<QTcpSocket*> _sockets;
};
#endif // MAINWINDOW_H
https://riptutorial.com/ 78
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QHostAddress>
#include <QAbstractSocket>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
_server(this)
{
ui->setupUi(this);
_server.listen(QHostAddress::Any, 4242);
connect(&_server, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::onNewConnection()
{
QTcpSocket *clientSocket = _server.nextPendingConnection();
connect(clientSocket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
connect(clientSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this,
SLOT(onSocketStateChanged(QAbstractSocket::SocketState)));
_sockets.push_back(clientSocket);
for (QTcpSocket* socket : _sockets) {
socket->write(QByteArray::fromStdString(clientSocket-
>peerAddress().toString().toStdString() + " connected to server !\n"));
}
}
void MainWindow::onReadyRead()
{
QTcpSocket* sender = static_cast<QTcpSocket*>(QObject::sender());
QByteArray datas = sender->readAll();
for (QTcpSocket* socket : _sockets) {
if (socket != sender)
socket->write(QByteArray::fromStdString(sender-
>peerAddress().toString().toStdString() + ": " + datas.toStdString()));
}
}
https://riptutorial.com/ 79
Read Qt Network online: https://riptutorial.com/qt/topic/9683/qt-network
https://riptutorial.com/ 80
Chapter 19: Qt Resource System
Introduction
The Qt Resource system is a way to embed files within your project. Each resource file can have
one or more prefixes and each prefix can have files in it.
Each file in the resources is a link to a file on the file system. When the executable is built, the files
are bundled into the executable, so the original file does not need to be distributed with the binary.
Examples
Referencing files within code
Let's say that inside a resources file, you had a file called /icons/ok.png
The full url of this file within code is qrc:/icons/ok.png. In most cases, this can be shortened to
:/icons/ok.png
For example, if you wanted to create a QIcon and set it as the icon of a button from that file, you
could use
https://riptutorial.com/ 81
Chapter 20: QTimer
Remarks
QTimer can also be used to request a function to run as soon as the event loop has processed all
the other pending events. To do this, use an interval of 0 ms.
// option 2: Passing 0 with the start call will set the interval as well.
QTimer *timer = new QTimer;
timer->start( 0 );
Examples
Simple example
The following example shows how to use a QTimer to call a slot every 1 second.
In the example, we use a QProgressBar to update its value and check the timer is working properly.
main.cpp
#include <QApplication>
#include "timer.h"
Timer timer;
timer.show();
return app.exec();
}
timer.h
#ifndef TIMER_H
#define TIMER_H
#include <QWidget>
https://riptutorial.com/ 82
class QProgressBar;
public:
Timer(QWidget *parent = 0);
public slots:
void updateProgress();
private:
QProgressBar *progressBar;
};
#endif
timer.cpp
#include <QLayout>
#include <QProgressBar>
#include <QTimer>
#include "timer.h"
Timer::Timer(QWidget *parent)
: QWidget(parent)
{
QHBoxLayout *layout = new QHBoxLayout();
layout->addWidget(progressBar);
setLayout(layout);
setWindowTitle(tr("Timer"));
resize(200, 200);
}
void Timer::updateProgress()
{
progressBar->setValue(progressBar->value()+1);
}
timer.pro
QT += widgets
HEADERS = \
timer.h
SOURCES = \
https://riptutorial.com/ 83
main.cpp \
timer.cpp
If a singleshot timer is required, it is quiet handy to have the slot as lambda function right in the
place where the timer is declared:
Due to this Bug (QTBUG-26406), this is way is only possible since Qt5.4.
In earlier Qt5 versions it has to be done with more boiler plate code:
This is useful when you need to update a UI element from a thread. Keep in mind lifetime of
anything the callback references.
DispatchToMainThread([]
{
// main thread
// do UI work here
});
Same code could be adapted to run code on any thread that runs Qt event loop, thus
implementing a simple dispatch mechanism.
Basic Usage
https://riptutorial.com/ 84
QTimer add the functionality to have a specific function/slot called after a certain interval (repeatedly
or just once).
The QTimer thus allows a GUI application to "check" things regularly or handle timeouts without
having to manually start an extra thread for this and be careful about race conditions, because the
timer will be handled in the main-event loop.
QTimer* timer = new QTimer(parent); //create timer with optional parent object
connect(timer,&QTimer::timeout,[this](){ checkProgress(); }); //some function to check
something
timer->start(1000); //start with a 1s interval
The timer triggers the timeout signal when the time is over and this will be called in the main-event
loop.
with myTime the time in ms, myObject the object which contain the method and
myMethodInMyObject the slot to call
So for example if you want to have a timer who write a debug line "hello !" every 5 seconds:
.cpp
void MyObject::startHelloWave()
{
QTimer::singleShot(5 * 1000, this, SLOT(helloWave()));
}
void MyObject::helloWave()
{
qDebug() << "hello !";
QTimer::singleShot(5 * 1000, this, SLOT(helloWave()));
}
.hh
private slots:
void helloWave();
https://riptutorial.com/ 85
...
};
https://riptutorial.com/ 86
Chapter 21: Signals and Slots
Introduction
Signals and slots are used for communication between objects. The signals and slots mechanism
is a central feature of Qt. In GUI programming, when we change one widget, we often want
another widget to be notified. More generally, we want objects of any kind to be able to
communicate with one another. Signals are emitted by objects when they change their state in a
way that may be interesting to other objects. Slots can be used for receiving signals, but they are
also normal member functions.
Remarks
Official documentation on this topic can be found here.
Examples
A Small Example
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 most from the features provided by
other frameworks.
The minimal example requires a class with one signal, one slot and one connection:
counter.h
#ifndef COUNTER_H
#define COUNTER_H
#include <QWidget>
#include <QDebug>
public:
Counter (QWidget *parent = 0): QWidget(parent)
{
m_value = 0;
/*
* The most important line: connect the signal to the slot.
*/
https://riptutorial.com/ 87
connect(this, &Counter::valueChanged, this, &Counter::printvalue);
}
public slots:
void printValue(int value)
{
qDebug() << "new value: " << value;
}
signals:
void valueChanged(int newValue);
private:
int m_value;
};
#endif
The main sets a new value. We can check how the slot is called, printing the value.
#include <QtGui>
#include "counter.h"
Counter counter;
counter.setValue(10);
counter.show();
return app.exec();
}
SOURCES = \
main.cpp
HEADERS = \
counter.h
The conventional connect syntax that uses SIGNAL and SLOT macros works entirely at runtime, which
https://riptutorial.com/ 88
has two drawbacks: it has some runtime overhead (resulting also in binary size overhead), and
there's no compile-time correctness checking. The new syntax addresses both issues. Before
checking the syntax in an example, we'd better know what happens in particular.
Let's say we are building a house and we want to connect the cables. This is exactly what connect
function does. Signals and slots are the ones needing this connection. The point is if you do one
connection, you need to be careful about the further overlaping connections. Whenever you
connect a signal to a slot, you are trying to tell the compiler that whenever the signal was emitted,
simply invoke the slot function. This is what exactly happens.
#include <QApplication>
#include <QDebug>
#include <QTimer>
struct OnTimerTickListener {
void onTimerTick()
{
qDebug() << "OnTimerTickListener::onTimerTick()";
}
};
OnTimerTickListener listenerObject;
QTimer timer;
// Connecting to a non-member function
QObject::connect(&timer, &QTimer::timeout, onTick);
// Connecting to an object member method
QObject::connect(&timer, &QTimer::timeout, &listenerObject,
&OnTimerTickListener::onTimerTick);
// Connecting to a lambda
QObject::connect(&timer, &QTimer::timeout, [](){
qDebug() << "lambda-onTick";
});
return app.exec();
}
Hint: the old syntax (SIGNAL/SLOT macros) requires that the Qt metacompiler (MOC) is run for any
class that has either slots or signals. From the coding standpoint that means that such classes
need to have the Q_OBJECT macro (which indicates the necessity to run MOC on this class).
The new syntax, on the other hand, still requires MOC for signals to work, but not for slots. If a
class only has slots and no signals, it need not have the Q_OBJECT macro and hence may not invoke
the MOC, which not only reduces the final binary size but also reduces compilation time (no MOC
https://riptutorial.com/ 89
call and no subsequent compiler call for the generated *_moc.cpp file).
While being better in many regards, the new connection syntax in Qt5 has one big weakness:
Connecting overloaded signals and slots. In order to let the compiler resolve the overloads we
need to use static_casts to member function pointers, or (starting in Qt 5.7) qOverload and friends:
#include <QObject>
public slots:
void slot(const QString &string) {}
void slot(const int integer) {}
signals:
void signal(const QString &string) {}
void signal(const int integer) {}
};
// COMPILE ERROR! the compiler does not know which overloads to pick :(
QObject::connect(a, &MyObject::signal, b, &MyObject::slot);
// this works, now the compiler knows which overload to pick, it is very ugly and hard to
remember though...
QObject::connect(
a,
static_cast<void(MyObject::*)(int)>(&MyObject::signal),
b,
static_cast<void(MyObject::*)(int)>(&MyObject::slot));
https://riptutorial.com/ 90
// there are also qConstOverload/qNonConstOverload and QConstOverload/QNonConstOverload,
the names should be self-explanatory
}
There is a MainWindow class that controls the Main Window view. A second window controlled by
Website class.
The two classes are connected so that when you click a button on the Website window something
happens in the MainWindow (a text label is changed).
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "website.h"
namespace Ui {
class MainWindow;
}
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void changeText();
private slots:
void on_openButton_clicked();
private:
Ui::MainWindow *ui;
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
https://riptutorial.com/ 91
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::changeText()
{
ui->text->setText("New Text");
delete webWindow;
}
void MainWindow::on_openButton_clicked()
{
webWindow = new Website();
QObject::connect(webWindow, SIGNAL(buttonPressed()), this, SLOT(changeText()));
webWindow->show();
}
website.h
#ifndef WEBSITE_H
#define WEBSITE_H
#include <QDialog>
namespace Ui {
class Website;
}
public:
explicit Website(QWidget *parent = 0);
~Website();
signals:
void buttonPressed();
private slots:
void on_changeButton_clicked();
private:
Ui::Website *ui;
};
#endif // WEBSITE_H
website.cpp
#include "website.h"
https://riptutorial.com/ 92
#include "ui_website.h"
Website::Website(QWidget *parent) :
QDialog(parent),
ui(new Ui::Website)
{
ui->setupUi(this);
}
Website::~Website()
{
delete ui;
}
void Website::on_changeButton_clicked()
{
emit buttonPressed();
}
Project composition:
SOURCES += main.cpp\
mainwindow.cpp \
website.cpp
HEADERS += mainwindow.h \
website.h
FORMS += mainwindow.ui \
website.ui
So the keypoints are the connections between signals and slots and the management of windows
pointers or references.
https://riptutorial.com/ 93
Chapter 22: SQL on Qt
Examples
Basic connection and query
The QSqlDatabase class provides an interface for accessing a database through a connection. An
instance of QSqlDatabase represents the connection. The connection provides access to the
database via one of the supported database drivers. Make sure to Add
QT += SQL
in the .pro file. Assume an SQL DB named TestDB with a countryTable that contines the next
column:
| country |
-----------
| USA |
#include <QtGui>
#include <QtSql>
bool ok = db.open();
if(ok)
{
QSqlQuery query("SELECT country FROM countryTable");
while (query.next())
{
QString country = query.value(0).toString();
qWarning() << country; // Prints "USA"
}
}
return app.exec();
}
https://riptutorial.com/ 94
It's often convenient to separate the SQL query from the actual values. This can be done using
placeholders. Qt supports two placeholder syntaxes: named binding and positional binding.
named binding:
QSqlQuery query;
query.prepare("INSERT INTO employee (id, name, salary) VALUES (:id, :name, :salary)");
query.bindValue(":id", 1001);
query.bindValue(":name", "Thad Beaumont");
query.bindValue(":salary", 65000);
query.exec();
positional binding:
QSqlQuery query;
query.prepare("INSERT INTO employee (id, name, salary) VALUES (?, ?, ?)");
query.addBindValue(1001);
query.addBindValue("Thad Beaumont");
query.addBindValue(65000);
query.exec();
Note that before calling bindValue() or addBindValue() you need to call QSqlQuery::prepare() once.
For this option to work you will need to have access to memory of the machine and must have
permissions to access shared memory. For using a shared memory connection it is required to set
lpc: in front of the Server string. Connection using the SQL Server Native Client 11 is made using
these steps:
https://riptutorial.com/ 95
if(db.open())
{
ui->statusBar->showMessage("Connected");
}
else
{
ui->statusBar->showMessage("Not Connected");
}
This option requires your ODBC Connection to have a full DSN. The Server string is setup by
using the Windows Computername and the Instancename of the SQL Server. The example
connection will be opened using SQL Server Native Client 10.0
QString connectString = "Driver={SQL Server Native Client 10.0};"; // Driver can also be {SQL
Server Native Client 11.0}
connectString.append("Server=SERVERHOSTNAME\\SQLINSTANCENAME;"); // Hostname,SQL-Server
Instance
connectString.append("Database=SQLDBSCHEMA;"); // Schema
connectString.append("Uid=SQLUSER;"); // User
connectString.append("Pwd=SQLPASS;"); // Pass
db.setDatabaseName(connectString);
if(db.open())
{
ui->statusBar->showMessage("Connected");
}
else
{
ui->statusBar->showMessage("Not Connected");
}
For opening a TCP/IP connection the server should be configured to allow connections on a fixed
port, otherwise you will first have to query for the currently active port. In this example we have a
fixed port at 5171. You can find an example for setting up the server to allow connections on a
fixed port at 1. For open a connection using TCP/IP use a tuple of the servers IP and Port:
if(db.open())
{
ui->statusBar->showMessage("Connected");
}
else
{
ui->statusBar->showMessage("Not Connected");
}
https://riptutorial.com/ 96
Read SQL on Qt online: https://riptutorial.com/qt/topic/10628/sql-on-qt
https://riptutorial.com/ 97
Chapter 23: Threading and Concurrency
Remarks
A few notes that are already mentioned in the official docs here and here:
• If an object has a parent, it has to be in the same thread as the parent, i.e. it cannot be
moved to a new thread, nor can you set a parent to an object if the parent and the object live
in different threads
• When an object is moved to a new thread, all of its children are also moved to the new
thread
• You can only push objects to a new thread. You cannot pull them to a new thread, i.e. you
can only call moveToThread from the thread where the object is currently living in
Examples
Basic usage of QThread
QThreadis a handle to a platform thread. It lets you manage the thread by monitoring its lifetime,
and requesting that it finishes its work.
In most cases inhering from the class is not recommended. The default run method starts an event
loop that can dispatch events to objects living in the class. Cross-thread signal-slot connections
are implemented by dispatching a QMetaCallEvent to the target object.
A QObject instance can be moved to a thread, where it will process its events, such as timer events
or slot/method calls.
To do work on a thread, first create your own worker class that derives from QObject. Then move it
to the thread. The object can run its own code automatically e.g. by using
QMetaObject::invokeMethod().
#include <QObject>
https://riptutorial.com/ 98
QThread workerThread;
public:
MyController() {
worker.moveToThread(&workerThread);
// provide meaningful debug output
workerThread.setObjectName("workerThread");
workerThread.start();
// the thread starts the event loop and blocks waiting for events
}
~MyController() {
workerThread.quit();
workerThread.wait();
}
void operate() {
// Qt::QueuedConnection ensures that the slot is invoked in its own thread
QMetaObject::invokeMethod(&worker, "doWork", Qt::QueuedConnection);
}
};
If your worker should be ephemeral and only exist while its work is being done, it's best to submit
a functor or a thread-safe method for execution in the thread pool via QtConcurrent::run.
QtConcurrent Run
If you find managing QThreads and low-level primitives like mutexes or semaphores too complex,
Qt Concurrent namespace is what you are looking for. It includes classes which allow more high-
level thread management.
Let's look at Concurrent Run. QtConcurrent::run() allows to run function in a new thread. When
would you like to use it? When you have some long operation and you don't want to create thread
manually.
#include <qtconcurrentrun.h>
void mainThreadFunction()
{
QFuture<void> f = run(longOperationFunction, "argToPass");
f.waitForFinished();
}
So things are simple: when we need to run another function in another thread, just call
QtConcurrent::run, pass function and its parameters and that's it!
QFuture presents the result of our asynchronous computation. In case of QtConcurrent::run we can't
cancel the function execution.
https://riptutorial.com/ 99
Invoking slots from other threads
When a Qt event loop is used to perform operations and a non-Qt-saavy user needs to interact
with that event loop, writing the slot to handle regular invocations from another thread can simplify
things for other users.
main.cpp:
#include "OperationExecutioner.h"
#include <QCoreApplication>
#include <QThread>
QThread thrd;
thrd.setObjectName("thrd");
thrd.start();
while(!thrd.isRunning())
QThread::msleep(10);
return 0;
}
OperationExecutioner.h:
#ifndef OPERATION_EXECUTIONER_H
#define OPERATION_EXECUTIONER_H
#include <QObject>
#endif // OPERATION_EXECUTIONER_H
OperationExecutioner.cpp:
#include "OperationExecutioner.h"
#include <QMetaObject>
#include <QThread>
#include <QDebug>
https://riptutorial.com/ 100
void OperationExecutioner::doIt1(int argi, char argc)
{
if (QThread::currentThread() != thread()) {
qInfo() << "Called from thread" << QThread::currentThread();
QMetaObject::invokeMethod(this, "doIt1", Qt::QueuedConnection,
Q_ARG(int,argi), Q_ARG(char,argc));
return;
}
OperationExecutioner.pro:
HEADERS += OperationExecutioner.h
SOURCES += main.cpp OperationExecutioner.cpp
QT -= gui
https://riptutorial.com/ 101
Chapter 24: Using Style Sheets Effectively
Examples
Setting a UI widget's stylesheet
You can set the desired UI widget's stylesheet using any valid CSS. The example below will set a
QLabel's text color a border around it.
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QString style = "color: blue; border: solid black 5px;";
ui->myLabel->setStylesheet(style); //This can use colors RGB, HSL, HEX, etc.
}
MainWindow::~MainWindow()
{
delete ui;
}
https://riptutorial.com/ 102
Credits
S.
Chapters Contributors
No
Build QtWebEngine
3 Martin Zhai
from source
CMakeLists.txt for
4 Athena, demonplus, Robert, Velkan, wasthishelpful
your Qt project
Communication
6 between QML and Gabriel de Grimouard, Martin Zhai
C++
12 QDialogs Wilmort
Qt - Dealing with
16 Jan, Rinat, Shihe Zhang, Zylva
Databases
Qt Container
17 demonplus, Tarod
Classes
https://riptutorial.com/ 103
18 Qt Network Gabriel de Grimouard
22 SQL on Qt Noam M
https://riptutorial.com/ 104