Hands-On Mobile and Embedded Development with Qt 5

5 (2 reviews total)
By Lorn Potter
  • Instant online access to over 7,500+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. Standard Qt Widgets

About this book

Qt is a world-class framework, helping you to develop rich graphical user interfaces (GUIs) and multi-platform applications that run on all major desktop platforms and most mobile or embedded platforms. The framework helps you connect the dots across platforms and between online and physical experience.

This book will help you leverage the fully-featured Qt framework and its modular cross-platform library classes and intuitive APIs to develop applications for mobile, IoT, and industrial embedded systems. Considerations such as screen size, device orientation changes, and small memory will be discussed. We will focus on various core aspects of embedded and mobile systems, such as connectivity, networking, and sensors; there is no IoT without sensors. You will learn how to quickly design a flexible, fast, and responsive UI that looks great. Going further, you will implement different elements in a matter of minutes and synchronize the UI elements with the 3D assets with high precision. You will learn how to create high-performance embedded systems with 3D/2D user interfaces, and deploy and test on your target hardware. The book will explore several new features, including Qt for WebAssembly.

At the end of this book, you will learn about creating a full software stack for embedded Linux systems using Yocto and Boot to Qt for Device Creation.

Publication date:
April 2019
Publisher
Packt
Pages
368
ISBN
9781789614817

 

Chapter 1. Standard Qt Widgets

Qt Widgets are not the new kid on the block, but they still do have their place in applications that target mobile and embedded devices. They are well formed, predictable and have standard UI elements.

Recognizable UI elements are found in Qt Widgets and work great on laptops, which are simply mobile desktops. In this chapter, you will learn to design standard looking applications. Basic widgets such as menus, icons, and lists will be discussed with an emphasis on how to constrain the user interface to medium and small-sized displays. Topics we will discuss include how to use Qt's dynamic layouts to handle orientation changes. Classes such as QGraphicsScene, QGraphicsView, and QGraphicsItem will be used. Layout API such as QVBoxLayout, QGridLayout, and QStackedLayout will be discussed.

In this chapter we will cover:

  • Using Qt Creator and Qt Widgets to create a mobile app and run on the device
  • Differences between desktop and mobile apps including screen size, memory, gestures
  • Using Qt Widgets in dynamic layouts for easy screen size and orientation changes
  • Using QGraphicsView for graphical apps
 

Hello mobile!


So you want to develop apps for mobile and embedded devices using Qt. Excellent choice, as Qt was made for cross-platform development. To get you started, we will run through the basic procedure of using Qt Creator to create, build and run an application. We will briefly examine different aspects to consider when creating mobile and embedded apps, such as how to use Qt Creator to add a menu. Adding a QWidget in the designer is not that difficult, and I will show you how.

Qt has a long history of running on mobile devices, starting with Qt Embedded, which was initially released in 2000. Qt Embedded was the base framework for the UI Qtopia, which was initially released on the Sharp Zaurus on the SL-5000D developer edition.

These days, you can develop an application using Qt and sell it in the iOS App Store, Android Google Play store, or other Linux mobile phones. Qt apps run on TVs and you can even see them running on entertainment systems in cars and planes. It runs on medical devices as well as industrial automation machines on factory floors.

There are considerations for using Qt on mobile and embedded devices such as memory constraints and display size constraints. Mobiles have touchscreens, and embedded devices might not have screens at all. 

When you install Qt, you can use the Qt Creator IDE to edit, build and run your code. It's free and open source, so you can even customize it. I once had a patch that customized Qt Creator in a way that would allow me to print out all the keyboard commands that is was using, so I could have a quick reference sheet. Let's take a quick look at Qt Creator, that was once known as Workbench.

Qt Creator

We are not going to go into any great detail about Qt Creator, but I thought I should mention it to demonstrate how we could go about using it to develop a cross-platformQWidgetbased application that runs on a desktop and mobile platform. Some differences between the two will be discussed. We'll then demonstrate how using dynamic layouts can help you target many different screen sizes and handle device orientation changes. You might already be familiar with Qt Creator, so we will refresh your memory.

Basic Qt Creator procedure

The basic procedure for cross-compiling and building apps that run on a mobile device are straight forward after you get set up. The procedure that we would hypothetically follow is:

  1. File | New FileorProject... | Qt Widgets Application, click the Choose... button
  2. Write some amazing code
  3. Select the Projects icon on the left side of Qt Creator, then pick which target platform you want like Qt 5.12.0 for iOS
  4. Hit Ctrl + B, or Command + B to build
  5. Hit Ctrl + R, orCommand + R to run
  6. Hit F5, or Command + Y to debug

For this first chapter, we will use Qt Widgets, which are UI elements that are more closely aligned to traditional desktop computer applications. They are still useful for mobile and embedded devices.

Qt Designer

Qt Creator comes with a design tool named Qt Designer. When you create a new template application, you will see a list of files on the left. It will open your application form in Qt Designer when you click on any .ui file.

Note

The source code can be found on the Git repository under the Chapter01-a directory, in the cp1 branch.

Navigate to Forms | mainwindow.ui and double click on that. This will open the UI file in Qt Creators Designer. A UI file is just a text file in the form of XML, and you can edit that file directly if you choose. The following image shows how it looks when opened in Qt Designer:

Let's start with something just about every desktop application has—a Menu. Your mobile or embedded application might even need a Menu. As you can see, there is a templateMenu that the Qt app wizard has produced for us. We need to customize this to make it usable. We can add some sub-menu items to demonstrate basic Qt Creator functionality.

Add a QMenu

Click on the application form where it saysMenuto add menu items. Type in something likeItem1, hit Enter. Add another menu item, as demonstrated in the following image:

If you were to build this now, you would have an empty application with a Menu, so let's add more to demonstrate how to add widgets from the list of widgets that is on the left side of Qt Creator.

Add QListView

Our UI form needs some content. We will build and run it for the desktop, then build and run it for the mobile simulator to compare the two. The procedure here is easy as drag and drop. 

 

 

On the left side of Qt Creator is a list of Widgets, Layouts and Spacers that you can simply drag and drop to place onto the template form and create your masterpiece Qt application. Let's get started:

  1. Drag a ListView and drop it on the form.
  1. Select Desktop kit and build and run it by hitting the Run button. Qt Creator can build and run your application in the same step if you have made any changes to the form or source code. When you run it, the application should look similar to this image:

That's all fine and dandy, but it is not running on anything small like a phone.

Qt Creator comes with iOS and Android simulators, which you can use to see how your application will run on a small screened device. It is not an emulator, which is to say it does not try to emulate the device hardware, but simply simulates the machine. In effect, Qt Creator is building and running the target architectures.

  1. Now select iOS Simulator kit, or Android from the Projects tool in green, as seen in the following image:

 

  1. Build and run it, which will start it in the simulator.

 

Here is this app running on the iOS simulator:

 

There you go! You made a mobile app! Feels good, doesn't it? As you see, it looks slightly different in the simulator. 

 

 

Going smaller, handling screen sizes


Porting applications which were developed for the desktop to run on smaller mobile devices can be a daunting task, depending on the application. Even creating new apps for mobiles, a few considerations need to be made, such as differences in screen resolution, memory constraints, and handling orientation changes. Touch screens add another fantastic way to offer touch gestures and can be challenging due to the differences in the size of a finger as point compared to a mouse pointer. Then there are sensors, GPS and networking to contemplate! 

Screen resolution

As you can see in the previous images in the Add QListView section, the application paradigms are fairly different between desktop and mobile phones. When you move to an even smaller display, things start to get tricky in regards to fitting everything on the screen.

Luckily, there are Qt Widgets that can help. The C++ classes QScrollArea, QStackedWidget and QTabbedWidget can show content more appropriately. Delegating your on-screen widgets to different pages will allow your users the same ease-of-navigation which a desktop application allows.

There might also be an issue on mobile devices while using QMenu. They can be long, unruly and have a menu tree that drills down too deeply for a small screen. Here's a menu which works well on a desktop:

On a mobile device, the last items on this menu become unreachable and unusable. We need to redesign this!

 

Menus can be fixed by eliminating them or refactoring them to reduce their depth, or by using something like a QStackedWidget to present the Menu options.

 

Qt has support for high (Dots Per Inch) DPI displays. Newer versions of Qt automatically compensate for differences between high DPI and low DPI displays for iOS and the Wayland display server protocol. For Android, the environmental variable QT_AUTO_SCALE_FACTOR needs to be set to true. To test different scale factors, set QT_SCALE_FACTOR, which works best with an integer, typically 1 or 2.

Let's run through a few examples of widgets and how they can be better used on differing screens:

  • Widgets like QScrollBar can be increased in size to better accommodate a finger as pointer, or better yet be hidden and use the widget itself to scroll. The UI usually needs to be simplified.
  • Long QListViews can present some challenges. You can try to filter or add a search feature for such long lists to make the data more accessible and eye pleasing on smaller displays.
  • Even QStackedWidget or QTabbedWidget can be too big. Don't make the user flick left or right more than a few pages. Anything more can be cumbersome and annoying for the user to be flicking endlessly to get at content.
  • QStyleSheets are a good way to scale for smaller display's, allowing the developer to specify customizations to any widget. You can increase the padding and margins to make it easier for finger touch input. You can either set a style on a specific widget or apply it to the entire QApplication for a certain class of widget.
qApp->setStyleSheet("QButton {padding: 10px;}");

or for one particular widget it would be:

myButton->setStyleSheet("padding: 10px;");

Let's apply this only when there is a touch screen available on the device. It will make the button slightly bigger and easier to hit with a finger:

if (!QTouchScreen::devices().isEmpty()) {
   qApp->setStyleSheet("QButton {padding: 10px;}");
}

Note

If you set one style with a style sheet, you will most likely need to customize the other properties and sub-controls as well. Applying one style sheet removes the default style.

Of course, it is also easy to set a style sheet in Qt Designer, just right click on the target widget and select, Change styleSheet from the context menu. As seen here on the Apple Mac:

Mobile phones and embedded devices have smaller displays, and they also have less RAM and storage.

Memory and storage

Mobile phones and embedded devices usually have less memory than desktop machines. Especially for embedded devices both RAM and storage are limited.

The amount of storage space used can be lowered by optimizing images, compressing if needed. If different screen sizes are not used, the images can by manually resized instead of scaling at runtime.

There are also heap vs stack considerations which generally always pass arguments into functions by reference by using the & (ampersand) operator. You will notice this in the majority of Qt code.

Compiler optimizations can greatly effect both performance and the size of executables. In general, Qt's qmake mkspec build files are fairly good at using the correct optimizations.

If storage space is a critical consideration, then building Qt yourself is a good idea. Configuring Qt using the -no-feature-* to configure out any Qt features you might not need is a good way to reduce it's footprint. For example, if a device has one static Ethernet cable connection and does not need network bearer management, simply configure Qt using -no-feature-bearermanagement. If you know you are not using SQL why ship those storage using libraries? Running configure with --list-features argument will list all the features available.

Orientation

Mobile devices move around (whodathunkit?) and sometimes it is better to view a particular app in landscape mode instead of portrait. On Android and iOS, responding to orientation changes are built in and occurs by default according to the users configuration. One thing you might need to do, is actually disable the orientation change. 

On iOS, you need to edit the plist.info file. For the key UISupportedInterfaceOrientations, you need to add the following:

<array><string>UIInterfaceOrientationLandscapeLeft</string></array>

On Android, edit the AndroidManifest.xml file android:screenOrientation="landscape"

If a picture frame device has a custom-built operating system, it might need it's photo viewing app to respond when the user switches orientations. That's where Qt Sensors can help out. More on that later in the first section of Chapter 7, Machines Talking.

Gestures

Touchscreen gestures are another way mobiles are different to desktops. Multi-touch screens have revolutionized the device world. QPanGesture, QPinchGesture and QSwipeGesturecan be used to great effect on these devices, and Qt Quick has components build for this type of thing—Flickable, SwipeView, PinchArea and others. More on Qt Quick later.

To use QGestures, first create a QList of containing the gestures you want to handle, and call the grabGesture function for the target widget.

QList<Qt::GestureType>gestures;
gestures<<Qt::PanGesture;
gestures<<Qt::PinchGesture;
gestures<<Qt::SwipeGesture;
for(Qt::GestureType gesture : gestures)
    someWidget->grabGesture(gesture);

You will need to derive from and then override the widgets event loop to handle when the event happens.

boolSomeWidget::event(QEvent*event)
{
if(event->type()==QEvent::Gesture)
return handleGesture(static_cast<QGestureEvent *>(event));
returnQWidget::event(event);
}

To do something useful with the gesture, we could handle it like this:

if(QGesture*swipe=event->gesture(Qt::SwipeGesture)) {
    if (swipe->state()==Qt::GestureFinished){
switch(gesture->horizontalDirection()) {
            case QSwipeGesture::Left:
            break;
            case QSwipeGesture::Right:
            break;
            case QSwipeGesture::Up:
            break;
            case QSwipeGesture::Down:
            break;
        }
    }
}

Devices with sensors also have access to QSensorGesture, which enable motion gestures such as shake. More on that later, in Chapter 7, Machines Talking.

 

Dynamic layouts


Considering that mobile phones come in all shapes and sizes, it would be ridiculous to need to provide a different package for every different screen resolution. Hence we will use dynamic layouts.

Note

The source code can be found on the Git repository under the Chapter01-layouts directory, in the cp1 branch.

Qt Widgets have support for this using classes such as QVBoxLayout and QGridLayout.

Qt Creator's designer is the easiest way to develop dynamic layouts. Let's go through how we can do that.

To set up a layout, we position a widget on the application form, and press Command or Control on the keyboard while selecting the widgets that we want to put in a layout. Here are two QPushButtons selected for use:

 

Next, click on the Horizontal Layout icon highlighted here:

You will then see the two widgets enclosed by a thin red box as in the following screenshot:

Now repeat this for the remaining widgets.

To make the widgets expand and resize with the form, click on the background and select Grid Layout:

Save and build this, and this app will now be able to resize for orientation changes as well as being able to work on different sized screens. Notice how this looks like in portrait (vertical) orientation:

Also note how this same application looks in landscape (horizontal) orientation:

As you can see, this application can change with orientation changes, but all the widgets are visible and usable. Using QSpacer will help guide the widgets and layouts positioning. They can push the widgets together, apart, or hold some to one side or another.

Of course, layouts can be used without touching Qt Designer. For example the following code:

QPushButton *button = new QPushButton(this);
QPushButton *button2 = new QPushButton(this);
QBoxLayout *boxLayout =new QVBoxLayout;
boxLayout->addWidget(button);
boxLayout->addWidget(button2);
QHBoxLayout *horizontalLayout = new QHBoxLayout;
horizontalLayout->setLayout(boxLayout);

QLayout and friends are the key to writing a cross-platform application that can accommodate the myriad screen resolutions and dynamically changing orientations of the target devices.

 

Graphics view


QGraphicsView, QGraphicScene and QGraphicsItem provide a way for applications based on Qt Widgets to show 2D graphics.

Note

The source code can be found on the Git repository under the Chapter01-graphicsview directory, in the cp1 branch.

Every QGraphicsView needs a QGraphicsScene. Every QGraphicsScene needs one or more QGraphicsItem.

QGraphicsItem can be any of the following: 

  • QGraphicsEllipseItem
  • QGraphicsLineItem
  • QGraphicsLineItem
  • QGraphicsPathItem
  • QGraphicsPixmapItem
  • QGraphicsPolygonItem
  • QGraphicsRectItem
  • QGraphicsSimpleTextItem
  • QGraphicsTextItem

Qt Designer has support for adding QGraphicsView . You can follow these steps to do so:

  1. Drag the QGraphicsView to a new application form and fill the form with a QGridLayout like we did before.
  1. Implement a QGraphicsScene in the source code and add it to the QGraphicsView
QGraphicsScene *gScene=newQGraphicsScene(this);
ui->graphicsView->setScene(gScene);
  1. Define a rectangle which will be the extent of the Scene. Here it is smaller than the size of the graphics view so we can go on and define some collision detection.
gScene->setSceneRect(-50, -50, 120, 120);

  1. Create a red rectangle to show the bounding rectangle. To make it a red color, create a QPen which will be used to paint the rectangle and then add the rectangle to the Scene. 
QPenpen=QPen(Qt::red);
gScene->addRect(gScene->sceneRect(),pen);
  1. Build and run the application. You will notice an app with a red bordered square on it.

As mentioned before, QGraphicsView shows QGraphicsItems. If we want to add some collision detection we need to subclass QGraphicsSimpleTextItem.

The header file for this is as follows:

#include<QGraphicsScene>
#include<QGraphicsSimpleTextItem>
#include<QGraphicsItem>
#include<QPainter>
classTextGraphic:publicQGraphicsSimpleTextItem
{
public:
TextGraphic(constQString&text);
voidpaint(QPainter*painter,constQStyleOptionGraphicsItem*option,QWidget*widget);
QStringsimpleText;
};

This custom class derived from QGraphicsSimpleTextItem will reimplement the paint(..) function, and use the collidingItems(...)function ofsceneto detect when something collides with our text object. Normally, collidingItems will return a QList of QGraphicsItems, but here it is just used to detect if any items are colliding.

Since this class holds only one item, it is known which item it is. If a collision is detected, the text changes. We don't need to check if the item's text is different before we change it, as the parent class's setText(...) does that for us.

TextGraphic::TextGraphic(constQString&text)
:QGraphicsSimpleTextItem(text),
simpleText(text)
{
}

voidTextGraphic::paint(QPainter*painter,constQStyleOptionGraphicsItem*option,QWidget*widget)
{
if(scene()->collidingItems(this).isEmpty())
QGraphicsSimpleTextItem::setText("BOOM!");
else
        QGraphicsSimpleTextItem::setText(simpleText);

    QGraphicsSimpleTextItem::paint(painter, option, widget);
}

Now create our TextGraphic object and add it to the Scene to use.

TextGraphic*text=newTextGraphic(QStringLiteral("QtMobile!"));
gScene->addItem(text);

If you build and run this, notice the text object will not move if we try to drag it around. QGraphicsItems have a flag property called QGraphicsItem::ItemIsMovablethat can be set to allow it to be moved around, either by the user or programmatically:

text->setFlag(QGraphicsItem::ItemIsMovable);

When we build and run this, you can grab the text object and move it around. If it goes beyond our bounding rectangle, it will change text, only returning to the original text if it moves inside the red box again.

If you wanted to animate this, just throw in a timer and change the text object's position when the timer fires.

Even with Qt Quick's software renderer, QGraphicsView is still a viable solution for graphics animation. If the target device's storage space is really tight, there might not be enough space to add Qt Quick libraries. Or a legacy app might be difficult to import to Qt Quick.

 

 

 

Summary


In this chapter we covered some of the issues facing mobile and embedded developers when trying to develop for smaller display devices, and how  QStyleSheets can be used to change the interface at runtime to adapt itself for using touchscreen inputs.

We discussed storage and memory space requirements, and the need to configure unneeded features out of Qt to make it have a smaller footprint.

We went through handling orientation changes and discussed using screen gestures such as Pinch and Swipe.

We learning how to use Qt Designer to add QLayouts to create dynamically resizing applications.

Finally, we discussed how to use QGraphicsView to utilize graphical elements such as graphical text and images.

Next, we will go through the next best thing since sliced bread for mobile and embedded development—Qt Quick and QML. Then we'll crack on with the real fancy stuff about graphical effects to spice up any interface!

About the Author

  • Lorn Potter

    Lorn Potter is a software developer, specializing in Qt and QML on mobile and embedded devices with his company, llornkcor technologies. He has worked for Trolltech, Nokia, Canonical, and was a freelance contractor for Jolla, Intopalo, and the Qt Company. He is the official maintainer of Qt Sensors, for which he developed the QSensorGestures API. He maintains the unsupported QtSystemInfo for the open source Qt Project and also works on Qt Bearer Management and Qt for WebAssembly. He has written blogs and articles for the Linux Journal. He started his career in tech as Trolltech's Qtopia Community Liaison. He currently resides in Australia and spends his spare time recording electronic psybient music for the project Brog on his website.

    Browse publications by this author

Latest Reviews

(2 reviews total)
Excllent book! In this book you will learn the features of the Qt/Qml framework.
Everything went perfectly, and the book itself is quite good.

Recommended For You

Qt5 C++ GUI Programming Cookbook - Second Edition

Use Qt 5 to design and build functional, appealing, and user-friendly graphical user interfaces (GUIs) for your applications.

By Lee Zhi Eng
Hands-On Embedded Programming with Qt

A comprehensive guide that will get you up and running with embedded software development using Qt5

By John Werner
Hands-On Functional Programming with C++

Learn functional programming and build robust applications using the latest functional features in C++

By Alexandru Bolboaca
C Programming Cookbook

A comprehensive guide with curated recipes to help you gain a deeper understanding of modern C.

By B. M. Harwani