Mindon.IDEA

Air off, Mind on ~ / Javascript+Golang, Sci, Health… /

Trying Cascades+QML App for Blackberry 10

“Research In Motion made another step towards the release of its new BlackBerry smartphones on Monday, announcing that it plans to unveil the devices and its new operating system on Jan. 30.”

“QML (Qt Meta Language or Qt Modeling Language) is a JavaScript-based, declarative language for designing user interface–centric applications. It is part of Qt Quick, the UI creation kit developed by Nokia within the Qt framework. QML is mainly used for mobile applications where touch input, fluid animations (60 FPS) and user experience are crucial. QML documents describe an object tree of elements.”

Here’s something I met during my first development using QML under Blackberry Native SDK IDE.

  • Link error or “undefined reference to `vtable for someSymbol’” issue

Update myproject.pro with something like LIBS += -lsystem to avoid lacking of libraries link error.

Manage source folders and files, header folders to avoid “undefined reference to `vtable for someSymbol’”

  • Save QML files in folder assets/ and make sure the folder is included in bar-description.xml

  • Seperated javascript file could be imported in QML by import “my.js” as MyDemo and functions could be called by MyDemo.method1

  • If using NavigationPane, you could import the public js in the QML of the NavigationPane and define public interface for all the pages.

e.g. demo.qml

import "demo.js" as Demo


NavigationPane {
    id: nav
    function notify( message ) {
    Demo.notify( message )
    }
}

usage e.g. in a page loaded into the NavigationPane

Page {
    Container {
        layout: StackLayout {
        }
        Button {
                text: qsTr("Test")
        onClicked: {
          nav.notify("something")
        }
        }
    }
}
  • Custom list item in a sub-folder share/DemoItem.qml

something like

import "share"
//...
ListView {
            listItemComponents: [
                ListItemComponent {
                    type: "item"
                    DemoItem {
                    }
                }
        dataModel: GroupDataModel {
                    id: recentlyDataModel
        }
        onCreationCompleted: {
                recentlyDataModel.clear()
            recentlyDataModel.insert({
            "message": "Hello world",
            "image": "asset:///images/demo.png"
        })
        }
            ]
}
  • Chat message display

component to display chat message

TextArea {
        editable: false
    text: "Hello :-)"
    inputMode: TextAreaInputMode.Chat
}
  • Using system dialogs inside QML

call these to import system dialog methods into QML

qmlRegisterType<bb::system::SystemDialog>("bb.system", 1, 0, "SystemDialog");
qmlRegisterType<bb::system::SystemPrompt>("bb.system", 1, 0, "SystemPrompt");
qmlRegisterType<bb::system::SystemToast>("bb.system", 1, 0, "SystemToast");
  • Use subscribe/publish methods to comunicate between QML and C++

set context

#include <bb/cascades/Application>
#include <bb/cascades/QmlDocument>
#include <bb/cascades/NavigationPane>

#include <bb/system/SystemDialog>
#include <bb/system/SystemPrompt>
#include <bb/system/SystemToast>

DemoTest::DemoTest(bb::cascades::Application *app)
: QObject(app)
{

    QmlDocument *qml = QmlDocument::create("asset:///demo.qml").parent(this);

    // create root object for the UI
    NavigationPane *navPane = qml->createRootObject<NavigationPane>();

    // set created root object as a scene
    if (navPane) {
    Demo *demo = new Demo();

    qml->setContextProperty("*demo", demo);

    // Set the main scene for the application to the NavigationPane.
    Application::instance()->setScene(navPane);
    }

}

definition in Demo class

signals:
    void publish(QString, QVariant);

called

QVariantMap info;
info.insert( "from", "mindon" );
info.insert( "to", "airoff" );
info.insert( "message", "mindon.github.com" );

emit publish( "MSG", info );

qml connect in demo.qml

function publish( type, data ) {

}
function subscribe( type, cb ) {

}
onCreationCompleted: {
    demo.publish.connect( nav.publish )
}

Then we could call methods of Demo by demo instance in the QML, at the same time Demo class could inform the QML by the single event signal publish.

Before this, Qt/QML is totally a stranger to me. Hope this helps when you start your first QML app for BB10.

Blackberry;QML;Qt;Cascades

Comments