A Qt QML Beginner’s Project: MotoRing, part 2 – Rewind and Reveal

Finally, here’s the much-demanded second part to this QML beginner-focused series.  Okay, one guy asked, but he sounded really interested.

I said at the end of the first article that I would progress to the next phase in this one.  But the request for a screenshot of the app at this point got me to thinking that it would be worth more to fledgling QML developers if I backed up and broke down the code.  So let’s do it.  There’s a lot to cover, so I’ll spread it across two or three articles.

First, the promised screenshot:

MotoRing, phase 1

There’s more going on here than my final app would really need, but I was working for two things here: one, to expand the original code example’s functionality for anyone following me, and also to provide visual feedback of functionality for my own drive trials.  Ultimately, the home screen will be very simple and the app will rely on a separate configuration screen (or menu) along with notification audio and dialogs screens.  For safety’s sake, and especially given that this app is to reduce driver interruptions, emphasis will be on audio.

As you can see, I placed units selection at the top of the screen.  That made it easy to toggle back and forth between miles-per-hour and kilometers-per-hour during testing.  Speed certainly doesn’t need the level of precision shown; I should just truncate at the decimal point.  The screen above shows that typical US measurements are selected (feet, miles) and the speed shown is in miles per hour.  I could also add more context (i.e., “MPH” or “KPH” after the speed readout) but that’s not necessary for this app.

Now, let’s dig into the code, starting with main.qml, which is automatically created for Qt Quick projects.

There’s the usual basic requirements of course.  In main.qml, the “home” code, we load the necessary libraries for QT Quick and MeeGo Harmattan:

import QtQuick 1.1
import com.nokia.meego 1.0

The actual declarative code describes the home page itself:

PageStackWindow {
    id: appWindow
    initialPage: mainPage
    showStatusBar: true

    MainPage {
        id: mainPage
    }
    ToolBarLayout {
        id: commonTools
        visible: true
        parent: appWindow.pageStack.currentPage

        Item {
            id: switchRow
            width: 300
            height: 32
            anchors.verticalCenter: parent.verticalCenter

            // Switch for power saving: toggle gps on/off
            Switch {
                id: gpsSwitch
                anchors.verticalCenter: parent.verticalCenter
                checked: false
                anchors.right: parent.right
                anchors.rightMargin: 50
            }
            Text {
                id:switchText
                font.pointSize: 24
                text: gpsSwitch.checked ? "GPS ON" : "GPS OFF"
                horizontalAlignment: Text.AlignRight
                anchors.verticalCenter: parent.verticalCenter
                anchors.right: gpsSwitch.left
                anchors.rightMargin: 25
                font.family: "Nokia Pure"
            }

        }
// menu not yet implemented
        ToolIcon {
            platformIconId: "toolbar-view-menu";
        }
    }
}

I’m still struggling to fully understand how to use the PageStackWindow element (and welcome all explanations and examples) but the functionality is clear: it identifies the content page(s) to load for main.qml.  In this case, we have MainPage.qml (which is also created by default) which contains our actual program and is selected via initialPage: mainPage.  (note: I still haven’t figured out how to manage multiple pages with this, and could use some help!)

I have customized the default main.qml content by removing some of the auto-generated stuff and replacing it with what my app needs.  In this case, an on/off switch (gpsSwitch) on the Toolbar (commonTools) at the bottom of the page.  The switch works in conjunction with a text box (switchText), so both elements are grouped into an Item called switchRow. The Item element, as explained here, makes such grouping (and therefore managing) of common and/or related items easy.  As a side note, I’m sure I don’t have to explain what the id property is doing for all elements… do I?  😉

To toggle the GPS status, we use text: gpsSwitch.checked ? “GPS ON” : “GPS OFF”. Think of this as a simple IF/THEN. When the switch is on, the text value is set to “GPS ON”.  (I’m thinking I can get rid of my two chunks of in-line JavaScript in MainPage.qml by doing something similar.)

If I understand right, showStatusBar: true makes the Toolbar visible.  You’ll also see a menu item referenced in the last code chunk.  I haven’t got to that yet, but I’m hoping I can use the popup menu for settings.

There really isn’t much to main.qml on this or most other projects I’ve looked at.  It’s my understanding that keeping the page loader simple and using individual pages for specific app features is the best practice.  Someone correct me if that’s wrong!

On a related note, while checking tour dates of musical groups I enjoy, I realized there wasn’t an event planner app for MeeGo Harmattan that would suit my purposes.  So I’ll make that another documented project, one that might actually be easier than this one.

One recurring, general gripe: I’m really perturbed by some common Qt Quick elements being documented, separately, as both Symbian and MeeGo types.  PageStackWindow is one example (note that I deliberately linked to MeeGo Harmattan documentation).  Why is this?

Next: I’ll parse out MainPage.qml…

5 responses to “A Qt QML Beginner’s Project: MotoRing, part 2 – Rewind and Reveal

  1. “””
    I still haven’t figured out how to manage multiple pages with this
    “””

    With a page stack you can just push, replace, and pop pages to your hearts content. You can even pass in variables to override bindings kind of like what you do on ToolbarLayout with “visible: true”

    Some example code (not all of the push methods work):
    https://github.com/epage/QmlFaq/blob/master/RecursiveViews/RecursivePageAnswer.qml

    ps Do you really need to set the parent for ToolBarLayout? I don’t think I’ve ever done that.

    • Thanks for the PageStack example code, Ed, I’ll check it later! Hopefully it’s easier to follow than what I’ve found so far…

      As for the ToolBarLayout parent setting– I’m not sure. That’s how the original code example was and I haven’t messed around with all of it yet. I’ll test that.

  2. What a coincidence! I was working on this yesterday and figured out how to have multiple pages!

    Create another QML file starting with an uppercase character and place everything wrapped around a Page element, give the Page element an id, now you should be able to reference this in the MainPage.qml file, for example mine is called Search.qml, the id of the page is searchPage, so I can say when a button is clicked i.e. onClicked: searchPage.visible = true.

  3. Pingback: Microsoft + Nokia Babies: Hate at a Distance, Love Up Close | Tabula Crypticum

Leave a comment