Preparing your Qt Quick gallery entry point

First of all, you need to link this project to our gallery-core library. We already covered how to link an internal library in Chapter 12Conquering the Desktop UI. For more details, refer to it. This is the updated gallery-mobile.pro file:

TEMPLATE = app 
 
QT += qml quick sql svg 
 
CONFIG += c++11 
 
SOURCES += main.cpp 
 
RESOURCES += gallery.qrc 
 
LIBS += -L$$OUT_PWD/../gallery-core/ -lgallery-core 
INCLUDEPATH += $$PWD/../gallery-core 
DEPENDPATH += $$PWD/../gallery-core 
 
contains(ANDROID_TARGET_ARCH,x86) { 
    ANDROID_EXTRA_LIBS =  
        $$[QT_INSTALL_LIBS]/libQt5Sql.so 
} 

Please notice that we made several changes here:

  • We added the sql module to deploy the dependency on your mobile device
  • We added the svg module for the button icons
  • The qml.qrc file has been renamed in gallery.qrc
  • We linked the gallery-core library
  • By default, the sql shared object (libQt5Sql.so) will not be deployed on your Android x86 device. You have to explicitly include it in your .pro file.

You can now use classes from the gallery-core library in our gallery-mobile application. Let's see how to bind C++ models with QML. This is the updated main.cpp:

#include <QGuiApplication> 
#include <QQmlApplicationEngine> 
#include <QQmlContext> 
#include <QQuickView> 
 
#include "AlbumModel.h" 
#include "PictureModel.h" 
 
int main(int argc, char *argv[]) 
{ 
    QGuiApplication app(argc, argv); 
 
    AlbumModel albumModel; 
    PictureModel pictureModel(albumModel); 
 
    QQmlApplicationEngine engine; 
 
    QQmlContext* context = engine.rootContext(); 
    context->setContextProperty("albumModel", &albumModel); 
    context->setContextProperty("pictureModel", &pictureModel); 
 
    engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml"))); 
 
    return app.exec(); 
} 

Our models will be instantiated in C++ and exposed to QML using the root QQmlContext object. The setContextProperty() function allows us to bind a C++ QObject to a QML property. The first argument will be the QML property name. We are only binding a C++ object to a QML property; the context object does not take ownership of this object.

Let's now talk about the mobile application itself. We will define three pages with specific roles:

  • AlbumListPage
    • Displays existing albums
    • Album creation
    • Album selection
  • AlbumPage
    • Displays existing pictures as thumbnails
    • Adds pictures in album
    • Album rename
    • Album deletion
    • Picture selection
  • PicturePage
    • Displays selected picture
    • Picture selection
    • Picture deletion

To handle the navigation, we will use a StackView component from Qt Quick Controls. This QML component implements a stack-based navigation. You can push a page when you want to display it. When the user requests to go back, you can pop it. Here is the workflow using a StackView component for our gallery mobile application. The page with the solid border is the page currently displayed on screen:

This is the implementation of main.qml:

import QtQuick 2.6 
import QtQuick.Controls 2.0 
 
ApplicationWindow { 
 
    readonly property alias pageStack: stackView 
 
    id: app 
    visible: true 
    width: 768 
    height: 1280 
 
    StackView { 
        id: stackView 
        anchors.fill: parent 
        initialItem: AlbumListPage {} 
    } 
 
    onClosing: { 
        if (Qt.platform.os == "android") { 
            if (stackView.depth > 1) { 
                close.accepted = false 
                stackView.pop() 
            } 
        } 
    } 
} 

This main file is really simple. The application is constructed around the StackView component. We set the id property to allow our StackView to be identified and referred to by other QML objects. The anchors property will set stackView to fill its parent, the ApplicationWindow type. Finally, we set the initialItem property to a page, AlbumListPage that will be implemented soon.

On Android, onClosing will be executed each time the user presses the back button. To mimic a native Android application, we will first pop the last stacked page before really closing the application.

At the top of the file, we define a property alias for the stackView. A property alias is a simple reference to another existing property. This alias will be useful to access stackView from other QML components. To prevent a QML component to crush the stackView we are using the readonly keyword. After initialization, the components can access the property but not change its value.