Friday, November 9, 2012

Porting Qt app to BlackBerry 10 SDK

Recently BB10 device is getting in to news for its Qt framework support. I got curious about it and decided to port my Harmattan Qt app to BB10 device. First of all I am glad that finally there will be a real main stream device that will support Qt as development framework.

After installing BB10 NDK and going through few sample application I realized that I need to create BlackBerry Cascades C++ project using its QNX Momentics IDE event though I just wanted to create plain Qt application. So I created the Cascades C++ project and merged my existing Qt App's code to BB10 project.

I was aware that in order to run the application I need to change Harmattan component used in QML to standard QML component but I wanted to check debugging support provided by Momentics IDE to debug Qt cpp code and QML code. So I started application and I was staring at while screen with no error message in console of IDE and seems like there is no support to debug QML code or Java script code. I added few debug message to identify problem but still did not see any message in console. I still don't know how to see those debug log from Qt app in BB10. I think there must be some installation problem.

In addition to this debug log problem, Its emulator is not working in normal mode on my HP Elitebook 6930p laptop with Ubuntu as OS. I always have to run it in safe mode.  While running it in Safe mode, I faced another major problem. The emulator spill out of my laptop's 15 inch screen. Default emulator resolution is so big, I have to scroll a lot to see the whole screen of device. It seems that controller utility provided with emulator is not supposed to work when emulator is running in safe mode. This is so discouraging. However I decided continue my porting effort.

So no debug log and huge emulator that my 15 inch laptop can not contain, I decided to first try to run my application using Qt Desktop version and once application is working fine on desktop Qt SDK. I merged my code back to BB10 project.

I needed to make some minor change relate to path before I can see anything running. In BB10, Qt application locate images and QML file in assets folder not from Qt's Resource file. So I made necessary changes to use Image and QML file from Assets folder. Actually you can specify where your image files and QML files are present in bar-descriptor.xml but I am using default assets folder only.

Following is how you can show QML file located in assets folder using QDeclarativeView.

    QScopedPointer view(new QDeclarativeView());
    view->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
    view->setResizeMode( QDeclarativeView::SizeRootObjectToView );
    view->setSource(QUrl("app/native/assets/main.qml"));
    view->showFullScreen();

So after this I was able to see my application in emulator. But my application was supported in landscape mode only so I need to make change to make it launch in landscape mode only. To make application support either Portrait or Landscape mode, you need to set aspectRatio tag in bar-descriptor.xml, and to disable auto orientation change you can set autoorients tag to false

Following is my entry into bar-descriptor.xml
    
<initialwindow>
    <aspectratio>landscape</aspectratio>
    <autoorients>false</autoorients>
    <systemchrome>none</systemchrome>
    <transparent>false</transparent>
</initialwindow>

So now my plain Qt Application is running fine in emulator, but my application keeps running even after its minimized. I realized that I need to capture BPS Event in order to detect application minimize and maximize event. I found good information here for this purpose.

Following is my code to detect application minimize event so I can pause my application.

static QAbstractEventDispatcher::EventFilter previousEventFilter = 0;

static bool bpsEventFilter(void *message)
{
    bps_event_t * const event = static_cast<bps_event_t>(message);

    if (event && bps_event_get_domain(event) == navigator_get_domain()) {
        const int id = bps_event_get_code(event);

		//unsigned int code = bps_event_get_code(event);
		switch ( id ) {

		case NAVIGATOR_WINDOW_INACTIVE:
		   qDebug() << "INFO: Window inactive";
		   break;

		case NAVIGATOR_WINDOW_ACTIVE:
		   qDebug() << "INFO: Window active";
		   break;

		case NAVIGATOR_WINDOW_STATE:
		   navigator_window_state_t state = navigator_event_get_window_state(event);
		   if (state == NAVIGATOR_WINDOW_FULLSCREEN) {
			   qDebug() << "INFO: Resume game";
		   } else {
			   qDebug() << "INFO: Pause game";
			   Utils::instance()->PauseGame();
		   }
		   break;
		}
    }

    if (previousEventFilter)
        return previousEventFilter(message);
    else
        return false;
}

This is how you add event handler in main function.
 previousEventFilter = QAbstractEventDispatcher::instance()->setEventFilter(bpsEventFilter);
So After all this my porting activity is almost complete. Now I need to learn how to submit application to BB10 store. Let's see how that goes.  So overall I feel BB10 provides nice Qt support for app development, emulator support needs to be improved though to be considered as useful ( at lest in my case).

4 comments:

  1. FYI: If I'm not mistaken, looking on the BB forum, you'll find how to define where you want to output your debug. It's not an install problem.
    Same for the size of the simulator.

    Cheers

    ReplyDelete
  2. ok, I will try to search BB forum then, will update post when found solution.

    ReplyDelete
  3. When did you change Harmattan component used in QML to standard QML component? Was it a big change? How did you substitute Harmattan component in case it has no alternative in standard QML component?

    ReplyDelete
    Replies
    1. I was using vary basic component like Text and Rect and other similar. But for some other which was not available in standart QML, i just took source from Harmattan Git repository and used those in my application.

      Delete