Ekkehard Gentz [Independent Software Architect, Consultant]

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

Published Thursday September 22nd, 2016
9 Comments on Qt Conference Apps – out of the Developer Trenches – Part 1
Posted in Community, Dev Loop, Qt World Summit | Tags: , ,

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: initialPlaceholder
            source: "pages/InitialItemPage.qml"
            active: true
            visible: false
            onLoaded: {
                // Show BUSY INDICATOR
                rootPane.initialItem = item
                item.init()
                // Now something is VISIBLE - do the other time-consuming stuff
                startupDelayedTimer.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: startupDelayedTimer
            interval: 300
            repeat: false
            onTriggered: {
                initialPlaceholder.item.showInfo("Initialize Data ...")
                dataManager.init()
                settings = dataManager.settingsData()
                dataUtil.setSessionFavorites()
                // … and so on ...
                // inject model into Destinations Repeater
                destinations.model = navigationModel
                // show the Navigation Bars (Drawer and Favorites)
                initDone = true
                // now NavigationBars available
                // show first destination
                rootPane.activateDestination(firstActiveDestination)
            }
        }

 

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.

Do you like this? Share it
Share on LinkedInGoogle+Share on FacebookTweet about this on Twitter

Posted in Community, Dev Loop, Qt World Summit | Tags: , ,

9 comments

Sandro Frenzel says:

Thanks for sharing!

I have read a little bit through the code on GitHub and find some design issues:

1) It seems that some Pages and Dialogs were rather hard coupled. That means, that you use IDs from the outside of other components. So, if you change the ID from a component you have to keep care of all cross references. This is not really a good style and hard to maintain.

2) Some Dialogs and Components are completly destroyed or out of scope if I change the orientation.

ekke ekke says:

1) This is a decision I did for all my projects to hard couple some IDs. I’m using a strict naming schema in all my apps. for me it’s easier to maintain. I’m using even same IDs for Qt and BlackBerry Cascades Apps. per ex. I’m always having a rootPane in main and if pushing another NavigationControl on top I know it’s always a navPane and so on.
You’re right I have to keep care about.
BTW: in my blog about Qt mobile x-platform development I explained some of these namings and why I did it.
2) I know about. Hopefully this weekend I’ll find the time to write a bug report. Seems that StackView not always is aware of current sizes.

ekke ekke says:

reason found that some components not resizing well if orientation changes
https://bugreports.qt.io/browse/QTBUG-56195
and I have a workaround so step by step will fix this.

Scorp1us says:

Your approach is pretty darn close to my own. But I don’t use many if any, QtQuick controls because v1 put a very bad taste in my mouth. I have been meaning to check them out again.

ekke ekke says:

it’s really worth to try out new Qt Quick Controls 2. They are the reason I decided to use Qt for my mobile Apps now.

MKnocker says:

Fantastic post! Just what I was looking for as I am starting to develop for mobile (I am a C++ developer).

Bernhard says:

Hi,

this is a comment, that I also posted on your blog, but as it seems like that my comment isn’t showing up yet, I’ll post it here as well (just to be sure):

first of all, the app looks really great. Awesome work and very well thought through.
I am also currently working on a Qt/QML based App (also material design based). It’s great to see that there are others out there,
that struggle with the same things. There are some moments, I really wish I would have chosen to develop the app natively, but I think the grass is always greener on the other side ;). All in all, I am pretty happy with Qt/QML. My impression is, that Qt is already a pretty good option for cross platform app development (and it’s getting better every release).

Regarding your app: One improvement I could think of, would be a “pull down to refresh” option for listviews. (similar to that https://material.google.com/patterns/swipe-to-refresh.html#swipe-to-refresh-usage ). I don’t know if it makes sense for your app or if the content is pretty much static, but I would really be curious how you would tackle the problem. I tried to implement such a behavior myself with a Canvas, that “builds up a circle” when the user pulls down, but I am not 100% happy with the result, because it results in overlapping MouseArea’s (one to catch the pull down and one that’s inside the delegate). And in order to delegate the event to the correct MouseArea, I implemented some hacky things for strange things that I am not really proud of 😉

Thanks again for sharing your experiences. Awesome work!

Have a nice day & greetings from Austria,
Bernhard

ekke ekke says:

Bernhard,
Have done this for some of my BlackBerry10 Cascades Apps.
Swipe-To-Refresh is on my todo list for Qt Apps. The conference app pulls updates and next years apps will use Push Services.
ekke
BTW: have answered to your question atr my blog, too.

Vladimir says:

The app lacks of iOS Flat Native look, the switch control cannot be drag and slide in the settings, but useful though.

Commenting closed.

Get started today with Qt Download now