QML Timer Workaround in BB10

July 18, 2013 Tony Wong

BlackBerry’s Cascades framework allows developers to add a lot of functionality in QML that would otherwise have to be created in C++. The platform is missing one important component however: a timer! Timers are especially useful when you need to create a workaround in your QML to make life easier. Need to defer a view calculation for just a moment later? Want to wait for layout changes in your app to finish, but aren’t exposed to the necessary signals? Right now, there’re only two options:

  • Import the QTimer class. Unfortunately, this will break Momentics’ QML previewer.
  • Call a C++ function, which waits for a QTimer, and then triggers a QML callback that you created. What a pain!

I’ve constructed a simple workaround made entirely from QML that won’t break the Momentics previewer, but is still easy to maintain and extend.

The trick is simple:

  1. Piggy back off of the built-in animations framework to provide the needed timing functionality. Use an animation to change the opacity of a control that is not visible to the user.
  2. Allow the timer owner to set the duration and start the animation countdown without needing to know anything about how time is kept.
  3. Expose a signal that will be emitted when the animation is finished.

I’ve created a sample app on GitHub demonstrating the whole thing working together. The meat of the code is also included below. I hope this will help you keep more of your UI code in QML where it belongs.

// QmlTimer.qml
import bb.cascades 1.0

Container { id: root
    opacity: 0.0

    property int duration: 0
    property bool timerActive: false

    signal triggered

    function startTimer() {
        if (duration == 0) {
            console.log("timer can't start when duration is 0");
            return;
        }

        if (timerActive == true) {
            console.log("timer is already active, not starting");
            return;
        }

        opacity = 0;
        timerActive = true;
        timerAnimation.play();
    }

    function stopTimer() {
        timerActive = false;
        timerAnimation.stop();
    }

    animations: [
        FadeTransition { id: timerAnimation
            fromOpacity: 0
            toOpacity: 1
            duration: root.duration
        }
    ]

    onOpacityChanged: {
        if (timerActive == true && opacity == 1) {
            timerActive = false;
            root.triggered();
        }
    }
}

About the Author

Biography

More Content by Tony Wong
Previous
Grails Profile: Netflix puts Lipstick on Apache Hadoop's Pig and More
Grails Profile: Netflix puts Lipstick on Apache Hadoop's Pig and More

Netflix uses Grails to support most of their extensive catalog of open source projects. Lipstick is one tha...

Next
Scaling with RabbitMQ @ Soundcloud
Scaling with RabbitMQ @ Soundcloud

SoundCloud has 100s of millions of users worldwide and transcodes 12 hours of audio every minute. Learn fro...

Enter curious. Exit smarter.

Learn More