Clone wiki

blackberry-py / Building HelloWorld

Building HelloWorld

The classic Hello World program makes a good starting point, since it shows the minimal structure necessary to build an app, and exercises the build and deploy process for newcomers.

The following steps show you how to build a HelloWorld app, but please note that HelloWorld is generally not useful as an example of how "real" development proceeds as it's overly simplified. After zipping through this exercise you'll likely want to learn more by reading the Tart Quick Start or heading to the Documentation Overview.

File: assets/main.qml

We'll start with the UI level itself, which we've done with QML. QML comes from Qt and is for many a key feature of Cascades. Although it's possible to write the entire UI using just C++, QML can make the task far easier in many cases. In any event, since we're using Python in preference to C++ for the business logic, using C++ for the UI wouldn't make much sense.

import bb.cascades 1.0
import "tart.js" as Tart

Page {
    id: root

    Label {
        id: label
    }

    function onMsgFromPython(data) {
        label.text = data.text;
    }

    onCreationCompleted: {
        Tart.init(_tart, Application);

        Tart.register(root);

        Tart.send('uiReady');
    }
}

That's longer than it would be if we merely wanted to hard-code some static text in our UI, but in this case we want to show how to send it from Python so we have a little extra code in place for that.

The first import finds the Cascades namespace, so we can use components like Page and Label.

The import "tart.js" as Tart line pulls in a small JavaScript library in support of the Python/QML messaging. (The location of this file is a current "wart" which we hope to remove some day. You don't actually put it in your local project assets/ folder, however, unless you're using the "tart quickdeploy" utility. Normally the "tart package" utility will merge in the tart.js file from the binary distribution automatically.)

The onMsgFromPython() function is used to receive text sent in a message from the Python code. For now all such messages wrap their data in a JavaScript object called data, and we pull out the text property to assign to the label.

The onCreationCompleted handler leverages a QML mechanism that executes the contained code after the component involved (our Page in this case) is completely constructed. We initialize the Tart code in tart.js, giving it two critical references, one being the _tart namespace exposed from our C++ launcher (i.e. TartStart), and the other being the Qt/Cascades Application object.

We also call Tart.register() and give it a reference to the page. This call identifies functions such as onMsgFromPython() and sets them up to be destinations for incoming messages with matching names (in this case the message "msgFromPython"). The convention with the "on" prefix and uppercasing the first letter is deliberately identical to how QML's automatic registration of signal handlers such as onCreationCompleted works, but is an unrelated mechanism.

Lastly, we fire off a message "uiReady" to the Python backend code. This is a convention used in all Tart apps to signal the backend that the UI is constructed and available to the user, giving your Python code a chance to load data or react in whatever way it wants.

File: app.py

This is a contrived example for demonstration purposes, as any real app would be significantly more complex. In short, we subclass the tart.Application class, and provide a method to receive the "uiReady" message from the matching Tart.send() call in the QML. The same "on" prefix and capitalized-message convention is used here to let Tart automatically find the appropriate place to deliver the message. Note that (currently) the Python side uses lowercase for its own "tart" module: this is a wart that we'll likely remove in later versions.

The tart.send() takes a single string as a message name, and arbitrary data sent always with keyword arguments (e.g. "text="). In effect, each keyword becomes a property in the "data" object on the receiving side in JavaScript, with associated data. Note that the data is sent by serializing it to JSON, which imposes a small overhead and a few restrictions. The overhead is ignorable for most purposes, and the restrictions usually are as well. A future version of Tart may implement this differently, for higher performance, without needing changes to existing code.

import tart

class App(tart.Application):
    def onUiReady(self):
        tart.send('msgFromPython', text='hello, world')

File: tart-project.ini

Every Tart app should have a tart-project.ini file, which specifies a few pieces of important metadata, and some optional parameters. If you supply this file, you can use the "tart package" utility to quickly and easily build a Bar file containing all the required files from your app and from Tart, with .py files pre-compiled to .pyc files, an automatic "DRAFT" overlay on your icon when not building for release, and more.

For our HelloWorld app we need very little content in this so we'll keep it really simple:

[project]

name: HelloWorld
title: BB-Tart HelloWorld
id: ca.microcode.bbtart.HelloWorld

Technically, each of these fields is optional, so we could even get away with a file containing nothing more than "[project]", for now.

Packaging the App

Note that if you haven't already done so, you'll need to install Tart and, unfortunately still for now, the BlackBerry Momentics IDE and Native SDK.

If you have those installed, make sure the NDK utilities are in your PATH (by running c:\bbndk\bbndk-env.bat or the equivalent for your platform). Note also that the NDK includes a copy of Python 2.7, which will probably interfere with what you're doing, since we need Python 3.2 (for now) to build stuff for BB10. If when you type "python" you get a 2.7 prompt, you may want to just rename the NDK's python.exe to python.exe.unused (or delete it... I'm not sure what use it is to us).

And... here's where you'll also need to learn about "debug tokens" and app signing on BlackBerry 10. Start here and come back when you've figured it out, as we don't have a tutorial written just yet.

If you've got all those things done, you'll want to make a tart.ini file and point it to your debug token. See Configuring Tart for more on that.

To actually invoke the Tart packager and put everything together, all you should need to do now is this:

tart.cmd package -mdebug path/to/myapp

# on Linux/OSX
tart.sh package -mdebug path/to/myapp

If that folder path/to/myapp contains your tart-project.ini file, you should see some console output ending with:

Info: Package created: HelloWorld.bar

With Tart 1.0 we get a 49,586 byte file as our output.

Deploying the App

Make sure the device is in development mode if you'll be signing a devmode app (i.e. one built with -mdebug).

In the following command, make the appropriate substitution for DEVIP (generally 169.254.0.1 if you're connected to the device via USB) and PASS (which is whatever you set your device password to be):

C:\devdir> blackberry-deploy -installApp DEVIP -password MYPASS -package HelloWorld.bar
Info: Sending request: Install
Info: Action: Install
Info: File size: 56469
Info: Installing ...
Info: Processing 56469 bytes
Info: Progress 100%...
actual_dname::ca.microcode.HelloWorld.testDev__HelloWorld650004ed
actual_id::testDev__HelloWorld650004ed
actual_version::0.0.1.5
result::success

If you see anything like the above, you should now see the app's icon on your device screen:

Hello World icon

If you tap the icon to launch the app and all went well, you'll see this:

Hello World screen

If something went wrong, read about troubleshooting your app.

If all went well, carry on with Quick Start or perhaps head over to look at some of the Sample Apps.

Updated