Qt Conference Apps – out of the Developer Trenches - Part 1

In a few weeks the Qt World Summit 2016 will open its doors in San Francisco and I have been given the chance to speak there about my experiences while developing the Qt World Summit 2016 Conference App. This article series here will give you some additional information to my presentation.

For nearly 40 years I have been developing software, where the last 8 years I have focused on mobile App Development. I started mobile App Development with BlackBerry OS7 (Java) followed by BlackBerry 10 native Apps (Qt 4.8, Cascades UI Controls).

In 2016 BlackBerry, for first time ever, started to build secure Android Phones and my customers asked for x-platform Apps. Personally, I liked the way BlackBerry 10 Apps were built using QML and Cascades. Fortunately Qt just started Qt 5.6 Tech Preview of new Qt Quick Controls 2. I did some first tests to see if Qt Quick Controls 2 will enable me to develop good looking and performant mobile Apps.

First steps went well so I decided to spend some more time and to give Qt 5.7 and Qt Quick Controls 2 a try in real-life projects. Over the last 4 years I built many mobile business Apps for Enterprise and SMB and I also did some Apps for Developer Conferences.

I asked Tero Kojo to develop the QtCon 2016 Conference App as a proof-of-concept to rely on new Qt Quick Controls 2. You can download the QtCon Conference App from Google Play (https://play.google.com/store/apps/details?id=org.ekkescorner.c2g.qtcon), Apple App Store (https://itunes.apple.com/us/app/qtcon-2016-conference-app/id1144162386), Amazon App Store (https://www.amazon.com/ekkescorner-QtCon-2016-Konferenz-App/dp/B01L7DVJTO), as APK (https://app.box.com/s/fgeo14re3hrp47shg915geo1q4gzyxrz) or build it by yourself from Open Source Github Repo (https://github.com/ekke/c2gQtCon_x).

The App was built without any extra native Code – pure Qt only. Feedback was great and I just started to do the Qt World Summit 2016 Conference App – Github Repo will be public soon. Hopefully this time the App will also be available for Windows 10 from Windows App Store. Special thanks to Maurice Kalinowski for his help, the QtCon Conference App is running on Windows 10, although I had some problems uploading this to Windows App Store.

There is a blog series about all my experiences using Qt Quick Controls 2 to develop mobile Apps (http://j.mp/qt-x), also a series in (German) Web & Mobile Developer Magazin and now some articles here at Qt Blog, too. You can expect some 3 - 4 articles here at Qt Blog about developing Qt Conference Apps.

All development is done in my spare time and my goal is to motivate mobile App Developers to try out Qt Quick Controls 2 to develop x-platform Apps. I never did Qt development before, also never did native Apps for Android, iOS or Windows but now I am able to develop and upload Apps to Google Play or Apple App Store :) I am also using Google Material Style to provide a modern mobile App feeling. Thanks to J-P Nurmi, Mitch Curtis and others for great hints HowTo customize Qt Quick Controls 2.

From my experiences over the last 6 months, developing mobile Apps with Qt 5.7 and Qt Quick Controls 2 is much more comfortable and easier than using Xamarin, React Native, Cordova, Angular or Ionic. The good news for all my friends from BlackBerry 10 community: there is a great amount of re-use of C++ Code from Cascades and also architecture style is similar using Signals/Slots and QObject* as data model.

Speed is key to success

The first impression of any mobile App with regards to User Experience comes from starting the App. The User should never have the feeling that an App is slow. Some of my recipes for a speedy start are below:

  • fast creation of C++ Classes
  • immediately show something on the screen
  • be dynamic: only instantiate UI Controls you really need

How am I doing this? Only instantiate C++ Classes, avoid any initialization as open Databases, load Cache Files and more.

DataServer::DataServer(QObject *parent) : QObject(parent)
{
    // Do NOTHING HERE
}

Use the fastest possible way to show some UI to the User. My root and main Navigation Control is a Drawer. The Drawer contains a list of “Destinations“, where a Destination is a specific area of the Application as

  • Home
  • Schedule
  • Speakers
  • Venue

01_drawer

Each Destination can be one of the Qt Quick Controls 2 Navigation Controls (http://doc.qt.io/qt-5/qtquickcontrols2-navigation.html) or Container Controls(http://doc.qt.io/qt-5/qtquickcontrols2-containers.html):

  • Pane
  • Page
  • StackView
  • SwipeView / Tab Bar

Inside the Drawer you can use a ListView to let the User select a Destination – take a look at Qt Quick Controls 2 Gallery Example. I‘m using a Repeater to create different types of Controls: Destinations, Divider, Header, …

To show the selected Destination best way is to use a StackView as your root UI Control and swap the content – so there‘s always only one Item at this root StackView.

02_destinations

To startup immediately don‘t create all the Drawer – Destinations ! This can easy be done with a little trick: define the Repeater without a data model.

        Repeater {
            id: destinations
            // Don‘t set the model here !
            // model: navigationModel
            Destination {
                id: destinationLoader
            }
        }

So nothing will be created now. To show something to the User create a lightweight Control as initialItem. I‘m using a BusyIndicator.

        // STACK VIEW INITIAL ITEM (BUSY INDICATOR)
        // immediately activated and pushed on stack as initialItem
        Loader {
            id: <em>initialPlaceholder</em>
            source: "pages/InitialItemPage.qml"
            active: true
            visible: false
            onLoaded: {
                // Show BUSY INDICATOR
                <em>rootPane</em>.initialItem = <em>item</em>
                <em>item</em>.init()
                // Now something is VISIBLE - do the other time-consuming stuff
                <em>startupDelayedTimer</em>.start()
            }
        }

The next trick is to start a Timer with a small delay to allow QML to show and animate the BusyIndicator. Then from Timer timeout execute all the initialization stuff and call some Q_INVOKABLE methods from your C++ Classes to load data from Cache and more.

As soon as this is done you can go on with creation of UI Controls. To trigger this set the Repeater Data Model and all the Destinations will be created and HomePage will become current Item on root StackView.

        Timer {
            id: <em>startupDelayedTimer</em>
            interval: 300
            repeat: false
            onTriggered: {
                <em>initialPlaceholder</em>.item.showInfo("Initialize Data ...")
                <em>dataManager</em>.init()
                <em>settings</em> = <em>dataManager</em>.settingsData()
                <em>dataUtil</em>.setSessionFavorites()
                // … and so on ...
                // inject model into Destinations Repeater
                <em>destinations</em>.model = <em>navigationModel</em>
                // show the Navigation Bars (Drawer and Favorites)
                <em>initDone</em> = true
                // now NavigationBars available
                // show first destination
                <em>rootPane</em>.activateDestination(<em>firstActiveDestination</em>)
            }
        }

 

Here we go: first „real“ Page is visible.

But wait: not all Destinations will really be created from the Repeater – this would take too much time and consume too much memory. All the Destinations are created dynamically using Loaders and I implemented some Activation Policies:

  • Immediate: The Control will be instantiated and remain. I‘m using this only for the first visible Page – the HomePage.
  • When-Selected: First time a User selects a Destination will create the Control and remain. This happens for all Destinations a User normaly will use while the App is running: Schedule, Speakers,...
  • While-Selected: Those Destinations are only created when needed and be destroyed if User changes the Destination. Candidates for this Policy: Help, Settings, About, ...

Take a look at the code how all of this is implemented, attend my Session at Qt World Summit 2016 in San Francisco (http://www.qtworldsummit.com/speakers/ekkehard-gentz/) or meet me at #QtWS16.

Stay tuned – next article will cover the QObject* Data Model I‘m using, Caching and Data Binding.


Blog Topics:

Comments