Persistence
In , Data, we created a framework for capturing and holding data in memory. However, this is only half of the story, as without persisting the data to some external destination, it will be lost as soon as we close the application. In this chapter, we will build on our earlier work and save our data to disk in a SQLite database so that it can live on beyond the lifetime of the application. Once saved, we will also build methods for finding, editing, and deleting our data. To get all these operations for free in our various data models, we will extend our data entities so that they can load and save to our database automatically, without us having to write boilerplate code in each class. We will cover the following topics:
- SQLite
- Primary keys
- Creating clients
- Finding clients
- Editing clients
- Deleting clients
Installing Qt
Lets start things off by visiting the Qt website at https://www.qt.io:
The site layout changes fairly frequently, but what you are looking for is to download Qt Open Source for Desktop & Mobile :
- From the top-level menu, select Products and then IDE & Tools
- Click on Start for Free
- Select Desktop & Mobile Applications
- Click on Get your open source package
If you continue to use Qt beyond these personal projects, ensure that you read the licensing information available on the Qt website (https://www.qt.io/licensing/). Upgrade to the commercial Qt license if the scope of your projects requires it or if you want access to the official Qt support and the benefits of a close strategic relationship with the Qt company.
The site will detect your operating system and suggest a recommended download:
On Windows, you will be recommended the online installer *.exe file, while on Linux you will be offered a *.run file, and a .dmg file if you are running Mac OS X. In all cases, download and launch the installer:
On Linux, once downloaded, you may need to first navigate to the *.run file and mark it as executable in order to be able to launch it. To do this, right-click on the file in the file manager and click on Properties . Click on the Permissions tab and tick the box that says Allow executing file as program .
After the initial welcome dialog, the first thing you are presented with is the option to sign up for or log in with a Qt account. Feel free to create one if you wish, but for now well go ahead and Skip :
You are then asked to select which components you wish to install.
Your first decision is which version(s) of the Qt framework you want. You can have multiple versions installed side by side. Let's select the latest and greatest (Qt 5.10 at the time of writing) and leave all the older versions unchecked.
Next, expand the selected version and you will see a secondary list of options. All the options where the description reads Qt 5.9.x Prebuilt Components for ... are what is known as a Kit . A K it is essentially a toolset enabling you to build your application with a specific compiler/ linker and run it on a particular target architecture . Each kit comes with Qt framework binaries compiled specifically for that particular toolset as well as necessary supporting files . Note that k its do not come with the referenced compiler; you will need to install those ahead of time. One exception to this on Windows is MinGW (which includes GCC for Windows) , which you can optionally install via the Tools component list at the bottom.
On Windows, that is exactly what well do, so we select the MinGW 5.3.0 32 bit kit and also the MinGW 5.3.0 development environment from the Tools section. On my (64-bit) machine, I already have Microsoft Visual Studio 2017 installed, so we will also select the MSVC 2017 64-bit kit to help demonstrate some techniques later in the book. On Linux, we select GCC 64-bit, while on Mac OS, we select macOS 64-bit (which uses the Clang compiler). Note that on Mac OS, you must have XCode installed, and it's a good idea to launch XCode at least once to give it an opportunity to complete its initialization and configuration.
Feel free to press pause, go and install whatever other IDEs or compilers you want to use, and then come back and pick the kits to match. It doesnt matter too much which you go forthe techniques explained throughout the book are applicable regardless of the kit, you may just get slightly different results. Note that the available kits you are presented with will differ depending on your operating system and chipset; for example, if you are on a 32 bit machine, you wont be offered any 64 bit kits.
Below the kits are some optional Qt APIs (such as Qt Charts), which we wont need for the topics covered in this book, but feel free to add them in if you want to explore their functionality. Note that they may have different licensing agreements from the core Qt framework.
Regardless of kits and APIs, you will note in the Tools section that Qt Creator is installed by default and that is the IDE we will be using throughout this book:
Once you are finished making your selections, click on Next and Update to kick off the installation .
It's generally a good idea to leave the installation location as the default for consistency across machines, but feel free to install it wherever you want.
Data models
Now that we have the infrastructure in place to be able to define data objects (entities and entity collections) and properties of various types (data decorators), we can move on and build the object hierarchy we laid out earlier in the chapter. We already have a default Client class created by Qt Creator, so supplement that in cm-lib/source/models with the following new classes:
Class | Purpose |
Address | Represents a supply or billing address |
Appointment | Represents an appointment with a client |
Contact | Represents a method of contacting a client |
Well start with the simplest of the modelsthe address.
address.h:
#ifndef ADDRESS_H #define ADDRESS_H
#include
#include #include #include
namespace cm { namespace models {
class CMLIBSHARED_EXPORT Address : public data::Entity { Q_OBJECT Q_PROPERTY(cm::data::StringDecorator* ui_building MEMBER building
CONSTANT) Q_PROPERTY(cm::data::StringDecorator* ui_street MEMBER street
CONSTANT) Q_PROPERTY(cm::data::StringDecorator* ui_city MEMBER city CONSTANT) Q_PROPERTY(cm::data::StringDecorator* ui_postcode MEMBER postcode
CONSTANT) Q_PROPERTY(QString ui_fullAddress READ fullAddress CONSTANT)public: explicit Address(QObject* parent = nullptr); Address(QObject* parent, const QJsonObject& json);