Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases now! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Mastering Qt  5

You're reading from   Mastering Qt 5 Create stunning cross-platform applications using C++ with Qt Widgets and QML with Qt Quick

Arrow left icon
Product type Paperback
Published in Aug 2018
Publisher Packt
ISBN-13 9781788995399
Length 534 pages
Edition 2nd Edition
Languages
Tools
Arrow right icon
Authors (2):
Arrow left icon
Robin Penea Robin Penea
Author Profile Icon Robin Penea
Robin Penea
Guillaume Lazar Guillaume Lazar
Author Profile Icon Guillaume Lazar
Guillaume Lazar
Arrow right icon
View More author details
Toc

Table of Contents (16) Chapters Close

Preface 1. Get Your Qt Feet Wet FREE CHAPTER 2. Discovering qmake Secrets 3. Dividing Your Project and Ruling Your Code 4. Conquering the Desktop UI 5. Dominating the Mobile UI 6. Even Qt Deserves a Slice of Raspberry Pi 7. Third-Party Libraries without a Headache 8. Animations - Its Alive, Alive! 9. Keeping Your Sanity with Multithreading 10. Need IPC? Get Your Minions to Work 11. Having Fun with Multimedia and Serialization 12. You Shall (Not) Pass with QTest 13. All Packed and Ready to Deploy 14. Qt Hat Tips and Tricks 15. Other Books You May Enjoy

Adding a task

We will now rearrange the layout of MainWindow to be able to display our todo tasks. At this moment, there is no widget where we can display our tasks. Open the MainWindow.ui file. We will use Qt designer to create the UI:

  1. Drag and drop Horizontal layout inside the central widget and rename it toolbarLayout
  2. Right-click on the central widget and select Lay out vertically
  3. Drag and drop the label, spacer, and button inside toolbarLayout
  4. Drag and drop Vertical layout under toolbarLayout (a blue helper line will be displayed) and rename it tasksLayout
  5. Add a vertical spacer under tasksLayout (again, check the blue helper line):

Voilà! Your MainWindow form is finished. Later in the chapter you will learn how to dynamically create and add some Task widgets to the empty tasksLayout.

To sum up, we have:

  • A vertical layout for centralWidget that contains the toolbarLayout item and the tasksLayout item.
  • A vertical spacer pushing these layouts to the top, forcing them to take up the smallest possible space.
  • Gotten rid of menuBar, mainToolBar, and statusBar. Qt Creator created them automatically, we simply don't need them for our purposes. You can guess their uses from their names.

Don't forget to rename the MainWindow title to Todo by selecting MainWindow in the Object Inspector window and editing the Qwidget | windowTitle property. Your app deserves to be named properly.


Press Shift + F4 in Designer mode to switch between the form editor and the source.

Now that the MainWindow UI is ready to welcome tasks, let's switch to the code part. The application has to keep track of new tasks. Add the following in the MainWindow.h file:

#include <QVector> 
 
#include "Task.h" 
 
class MainWindow : public QMainWindow 
{ 
    // MAINWINDOW_H 
 
public slots: 
    void addTask(); 
 
private: 
    Ui::MainWindow *ui; 
    QVector<Task*> mTasks; 
};

The QVector is the Qt container class providing a dynamic array, which is an equivalent of std::vector. Generally speaking, the rule says that STL containers are more customizable, but they may miss some features compared to Qt containers. If you use C++11 smart pointers, you should favor std containers, but we will get into that later.

In the Qt documentation of QVector, you may stumble upon the following statement: For most purposes, QList is the right class to use. There is a debate about this in the Qt community:

  • Do you often need to insert objects larger than a pointer at the beginning or in the middle of your array? Use a QList class.
  • Need contiguous memory allocation? Less CPU and memory overhead? Use a QVector class.

The already-added addTask() slot will now be called each time we want to add a new Task object to the mTasks function.

Let's fill our QVector tasks each time addTaskButton is clicked. First, we connect the clicked() signal in the MainWindow.cpp file:

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow), 
    mTasks() 
{ 
    ui->setupUi(this); 
    connect(ui->addTaskButton, &QPushButton::clicked,  
    this, &MainWindow::addTask); 
}; 
As a best practice, try to always initialize member variables in the initializer list and respect the order of variable declarations. Your code will run faster and you will avoid unnecessary variable copies. For more information, take a look at the standard C++ documentation at https://isocpp.org/wiki/faq/ctors#init-lists.

The body of the addTask() function should look like this:

void MainWindow::addTask() 
{ 
        qDebug() << "Adding new task"; 
        Task* task = new Task("Untitled task"); 
        mTasks.append(task); 
        ui->tasksLayout->addWidget(task); 
} 

We created a new task and added it to our mTask vector. Because the Task object is a QWidget, we also added it directly to tasksLayout. An important thing to note here is that we never managed our new task's memory. Where is the delete task instruction? This is a key feature of the Qt Framework we started to mention earlier in the chapter; the QObject class parenting automatically handles object destruction.

In the preceding code snippet, the ui->tasksLayout->addWidget(task) call has an interesting side-effect: the ownership of the task is transferred to the layout's widget. The QObject* parent defined in the Task constructor is now centralWidget of the MainWindow. The Task destructor will be called when MainWindow releases its own memory by recursively iterating through its children and calling their destructor.

This feature has interesting consequences. First, if you use the QObject parenting model in your application, you will have much less memory to manage. Second, it can collide with some new C++11 semantics, specifically the smart pointers. We will get into the details about this in later chapters.

You have been reading a chapter from
Mastering Qt 5 - Second Edition
Published in: Aug 2018
Publisher: Packt
ISBN-13: 9781788995399
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime