Cyjan's Blog

I don't know why are you here, but enjoy.


Epstein didn't kill himself | Design | General
Politically Incorrect | Raspberry PI | Technologic
btw I'm using Ubuntu Touch

Multiple pages + code cleanup - Ubuntu Touch clicker app

July 25, 2020 | btw I'm using Ubuntu Touch

In the previous post, we have created a shop where you could buy cats for dogecoin, (and the cats helped you earn dogecoin so you could buy more cats... and so on). But the shop was on the same page as the rest of the app's content, which doesn't look good, that's why I've moved it to separate a file and screen. Also, the way I have used database wasn't the best way, and I've updated it, code is now much cleaner. Take look at the video tutorial (or rather making of this article) and source code.

Multiple pages view

Starting from qml/Main.qml, we have added import "./scripts/LoadPage.js" as LoadPage to the beginning of it and added

PageStack {
    id: mainStack
}

inside of the root element, we will use this PageStack to push our pages onto it.

Then I've moved pretty much everything from the Page {...} block to qml/pages/Shop.qml and qml/pages/Home.qml and because not much has changed in them (I've copy-pasted them from Main.qml and edited only a bit) check git repo if you want to check what's inside.

Button {
    ...
    onClicked: {
        LoadPage.load('Shop')
    }
}

The most notable change is that on every page we have added this Button to switch between them that used load function defined in qml/scripts/LoadPage.js

    function load(page) {
        var path = "../pages/%1.qml".arg(page)
        var p = Qt.resolvedUrl(path)
        mainStack.push(p)
    }

Which took page string as an argument, and pushed it's content to PageStack element defined in qml/Main.qml. So using it like load('Home') will load file qml/pages/Home.qml and push it to the PageStack.

Code cleanup

So, I've decided to add the following changes into Component.onCompleted in qml/Main.qml file

Cooponent.onCompleted: {
    LoadPage.load("Home")
    DB.get('doge', function (res) {
        doge = Math.round(Number(res))
    })
    DB.get('item_cat', function (res) {
        item_cat = Math.round(Number(res))
    })
    function Timer() {
        return Qt.createQmlObject("import QtQuick 2.0; Timer {}", root);
    }
    var timer = new Timer();
    timer.interval = 1000;
    timer.repeat = true;
    timer.triggered.connect(function () {
        doge += item_cat*1
        DB.set('doge', doge);
        DB.set('item_cat', item_cat)
    })
    timer.start();
}

As you may see, the timer is now handling setting things to our DB, which means that we can use properties instead of database functions. This made my life easier.

As a bonus, I've added one small line in qml/pages/Shop.qml file in catbuybtn's color property:

color: if (doge >= 100) { UbuntuColors.green } else { UbuntuColors.red }

This means that our button will be green when we can afford to buy a cat, and red if we can't buy it.