QtInfo available in Nokia Store

Another project that I have been blogging about every now and then has made it to Nokia Store!

QtInfo was a project started by Attila Csipa for creating a utility that would quickly and easily show as much information as possible of the Qt environment in which the application is run. Another goal was to create an example application that would show how to dig up the information using Qt APIs.

I have been contributing mostly UI related stuff to the project. Anyway, the application started to be quite good so we decided to make it available (for Symbian at the moment) in Nokia Store. Lucian Tomuta did the honors of packaging the application and going through the Nokia Store QA process, and now Symbian version of the app is available for download in the store: QtInfo in Nokia Store.

By no means is the application exclusive to mobile devices, the sources compile quite nicely also for desktop platforms like Windows, Linux or Mac. Of course the need for this kind of an application is the biggest on mobile, especially Symbian where Qt versioning can be a bit hairy.

If you want to see how the implementation is done, source code of the application is available on the QtInfo project page.

Cute Colors available in Nokia Store

Some time ago I blogged about a coloring book app that I did for an internal team event at work. Finally I had time to polish it to make it good enough to be published in Nokia Store.

Since the app is not tied to any platform specific features, it was very easy to create versions of it for both Nokia N9 and Symbian (Belle or later) devices.

There are not really that many changes in functionality to what you can see in the video that I made for the previous blog post, except for new and hopefully better graphics. One noteworthy thing is that the app now uses the new PinchArea element from Qt Quick 1.1, which makes pinching a lot less temperamental than in the video. :)

You can download Cute Colors from the Nokia Store by clicking here: Cute Colors in Nokia Store

Screenshot of the N9 version (Symbian one looks exactly the same but at lower resolution).

On-Device Debugging of QML Applications

I haven’t been able to get on-device debugging of QML application working on Symbian. Supposedly some people have been successful with it already earlier, but no matter what I have tried, I have never been able to get it to work properly.

All is different with the latest Qt SDK with Qt Creator 2.3.1 and Qt 4.7.4. To get on-device debugging to work I simply needed to follow the instructions in Qt SDK documentation. In short:

  • Install Qt 4.7.4, CODA and QML viewer on the Symbian Device (the SIS files are available in QtSDK\Symbian\sis\Symbian^3\Qt\4.7.4 and QtSDK\Symbian\sis\Symbian^3\CODA)
  • Start CODA on the device
  • Link the project against QML debugging library (Projects->Symbian Device->Build->Build Steps)
  • Check the “Debugger: QML” check box under Symbian Device->Run settings

After the steps above all it takes to debug my application on device is to select Symbian target in Qt Creator and click on the “Start debugging” button.

So, what does work? In short, everything. :) Breakpoints in C++ or JavaScript code, QML inspector and QML script console work as expected.

QML Inspector showing the properties of a ToolButton

The most impressive part for myself is the ability to edit QML code at runtime and have the changes automatically applied to the running QML application on device. This makes trying out different things so much faster.

I’m lovin’ it.

Split screen text input done properly

Some time ago I blogged about hacking split screen text input to QML on Symbian. Starting from Qt 4.7.4 enabling split screen editors in QML becomes much easier.

Already Qt 4.7.3 defines an ApplicationAttribute flag Qt::AA_S60DisablePartialScreenInputMode for disabling partial screen input mode. By default the flag is set to true. In Qt 4.7.3 this flag does not do anything from QML point of view. Starting from Qt 4.7.4 the flag can be used to enable split screen input for QML text editors with proper functionality like automatically moving the editor if it would be obscured by the on-screen keyboard.

Enabling the split screen keyboard can be done simply by setting the Qt::AA_S60DisablePartialScreenInputMode flag to false somewhere in the main.cpp, like this:

    QCoreApplication::setAttribute(Qt::AA_S60DisablePartialScreenInputMode, false);

Below you can see two screenshots of split screen inputs working in an application after adding the one line of code above.


  

A Qt Quick Components TextField anchored to the bottom of the screen with OSK closed and open

Qt 4.7.4 for Symbian is already available as a beta target with the latest version of Qt SDK, it is easy to test if enabling the split screen keyboard causes some issues in applications. Since Qt 4.7.4 is not available in Smart Installer yet, deploying split screen-enabled applications to Nokia Store needs to wait some more time.

However, since the flag that is needed to enable split screen input mode is available already in Qt 4.7.3, I don’t see any harm in adding the code that enables split screen input already now.

Also note that at the moment the application must have SwEvent capability in order to support predictive text input in split screen mode.

Multithreaded audio using QAudioOutput

While working on an app I noticed that if the QML UI is running animations and at the same time I’m trying to use QAudioOutput to play sound effects the animation becomes choppy quite easily, at least on (Symbian) device. I guess the cause for the problem is that audio processing is happening in the same thread that is running the event loop.

The solution to the problem is quite obvious – move the audio related stuff to a different thread. However, doing this required some tinkering, so I’m documenting the solution here in case somebody else is facing the same problem. Of course, this solution is in no way exclusive to audio output, it could just as well used to do any (QML or C++ -initiated) processing in a separate thread.

In my implementation I’m using two C++ classes, SfxPlayer and SfxThread. SfxPlayer gets exposed to QML side and it contains one slot, play(). The only purpose of the class is to contain an SfxThread object and to work as a proxy for invoking methods on the other thread.

sfxplayer.h

#ifndef SFXPLAYER_H
#define SFXPLAYER_H

#include <QObject>
#include "sfxthread.h"

class SfxPlayer : public QObject
{
    Q_OBJECT
public:
    explicit SfxPlayer(QObject *parent = 0);

signals:

public slots:
    void play();

private:
    SfxThread _sfxThread;
};

#endif // SFXPLAYER_H

sfxplayer.cpp

#include "sfxplayer.h"

SfxPlayer::SfxPlayer(QObject *parent)
    : QObject(parent)
{
}

void SfxPlayer::play()
{
    // Call playInternal of SfxThread (and invoke it in the other thread)
    QMetaObject::invokeMethod(&_sfxThread, "play", Qt::QueuedConnection);
}

The thing that caused a bit of head-scratching was how to make the player thread actually do the processing in the other thread instead of the caller. The solution is to call QObject::moveToThread(this); in the constructor of the thread.

sfxthread.h

#ifndef SFXTHREAD_H
#define SFXTHREAD_H

#include <QThread>
#include <QAudioOutput>
#include <QBuffer>
#include <QQueue>

class SfxThread : public QThread
{
    Q_OBJECT
public:
    explicit SfxThread(QObject *parent = 0);
    ~SfxThread();
    void run();

signals:

public slots:
    void play();
    void playerStateChanged(QAudio::State state);
private:
    void playNext();
    void play(QString& filename);

    QAudioOutput *_ao;
    QAudioFormat _af;
    QBuffer _buf;

    QQueue<QString> playlist;
};

#endif // SFXTHREAD_H

sfxthread.cpp

#include <QFile>
#include <QApplication>
#include "sfxthread.h"

SfxThread::SfxThread(QObject *parent) :
    QThread(parent)
{ 
    ...do precaching etc of the sounds here

    start();

    // Move event processing of SfxThread to this thread
    QObject::moveToThread(this);
}

SfxThread::~SfxThread()
{
    quit();
    wait();
}

void SfxThread::play()
{
    playlist.append(...);
    playNext();
}

// Plays the next file from queue
void SfxThread::playNext()
{
    if (playlist.length() == 0 || _ao->state() == QAudio::ActiveState) {
        return;
    }
    _ao->stop();
    _buf.close();
    play(playlist.dequeue());
}

void SfxThread::play(QString& filename)
{
    // load content here
    QByteArray *ptr = ...

    _buf.setBuffer(ptr);
    _buf.open(QIODevice::ReadOnly);

    _ao->setBufferSize(_buf.size());
    _ao->start(&_buf);
}

void SfxThread::playerStateChanged(QAudio::State state)
{
    // Play finished, play next clip
    if (state == QAudio::IdleState)
    {
        playNext();
    }
}

void SfxThread::run()
{
    ...set audio format here (_af.setCodec etc)
    
    _ao = new QAudioOutput(_af);

    connect(_ao, SIGNAL(stateChanged(QAudio::State)), this, SLOT(playerStateChanged(QAudio::State)));

    exec();
}

That’s it! You can now expose the SfxPlayer object to QML. Calling .play(); in QML will now just invoke the play method of SfxThread in the new thread that is running it’s own event loop.

Windows Phone

I created a new blog for talking about things related to Windows Phone. This blog has been (and will be) about Qt and I plan to continue blogging also about it when I feel that I have something interesting to say. :)

You can find the new blog from http://wpdevsource.wordpress.com/

QtInfo goes Qt Quick components (on Symbian)

Some time ago I blogged about the QtInfo project which aims to provide a simple tool for figuring out all sorts of information about the Qt installation on your device. The UI of the application didn’t really work that well on Symbian, so we decided to do something about it.

Qt Quick components provide a very convenient way to create a modern looking UI for a QML application. The components are of course mostly useful for “productivity” applications – like QtInfo – that don’t need too flashy graphics. After a little (very little, in fact) investigation into how PageStack, ToolBar, ToolButton, ListItem etc. work I ended up with the UI that you can see below. If you’re interested in how the UI has been implemented, you can find the QML sources here.

To make the change more obvious I attached a screenshot of the QWidget-based UI as a comparison. I would say that it’s quite a nice result considering that I only spent a couple of hours with it.


  

From old and tired to new and fresh (screenshots are from QtInfo running on Nokia N8)

In addition to making the UI more pleasing to the eye the Qt Quick components also provide some usability improvements like flick scrolling on the information list and buttons that are easier to hit with a finger.

The QML UI is implemented in such a way that if QtDeclarative module or Qt Quick components are not available the application will fall back to QWidget-based UI. The check is implemented by first testing if QtDeclarative module is present. If it is, the application tries to load a bit of QML that imports the com.nokia.symbian 1.0 module. The QML based UI is enabled if loading succeeds, otherwise the old UI will be used.

The old UI also struggled with orientation changes, with Qt Quick components (and QML in general) handling landscape orientation became really easy. Since the UI is not too complex and there’s no layout changes when moving from portrait to landscape, I did not need to do any changes to the QML code for landscape orientation to work nicely.

QtInfo in landscape orientation on Nokia N8

Here’s one more screenshot. In QtInfo I’m using a SelectionDialog for selecting where to share or copy data.

SelectionDialog for selecting where to share data

In my Coloring Book blog post I was raving about how easy it is to create nice looking UIs with Qt Quick. With the Qt Quick components the ease of development just became even better. The things that have impressed me the most so far are PageStack concept for doing automatic view transitions and the ToolBar for command handling. Also it’s nice to finally have a Button, I’m a bit tired of creating Button.qml’s. :)

Another problem when creating the high-level UI components yourself has been that making the application fit the platform and the other applications has not been too easy, especially if you don’t have a skilled graphics designer at hand. Qt Quick components helps a lot in this, for example for QtInfo I did not need to create any graphics myself, which saved a huge amount of time.

QtInfo does not have Smart Installer packaged with it. Because of this Qt Quick Components will not get automatically installed, so you must manually install the Qt Quick Components for Symbian package to enable the new UI. Unless, of course, you already have Qt Quick components installed on your phone. Note that the sis file that we have on the project page does not yet contain the new stuff, updated sis file will be available soon.Installer sis is now available under featured downloads on the project page (qtinfo_3.0_selfsigned.sis).

Split screen text input for QML text editors on Symbian

The normal VKB on Symbian^3

The default VKB that appears when e.g. QML TextInput gets focus.

Update 23.08.2011: There’s a more fully featured split screen keyboard implementation available here: http://talvbansal.com/2011/08/22/split-entry-on-symbian-3-devices/, check it out!

Symbian^3 has had support for split screen virtual keyboard since the beginning. However, in the first firmware versions the editors take up the whole screen when active. I don’t particularly like this behavior since it loses the context of the text input field (i.e. “what did I need to type in here?”), and if there are several text input fields in a view it may be difficult to see which field is currently active. Additionally in QML applications that tend to be graphically quite flashy the fullscreen VKB often looks a bit clumsy.

The other option on Symbian^3 is to use split screen virtual keyboard that does not cover the whole application UI, which pretty much the same as the VKB implementations on most other mobile platforms. There is an open bug report for making Qt support this, but it will only get implemented in Qt 4.7.4.

Luckily it is possible to hack the split screen VKB to appear already now on all Symbian^3 devices. You can download an example application that has two split view-enabled TextInput elements here, it should compile easily with Qt SDK 1.1. If you just want to try it out the sis file is available here. Making the split screen VKB appear instead of the fullscreen one boils down to being able to set the partial screen input flag for the text editors. Here’s a code snippet from the example application, which does exactly that:

#if defined(Q_OS_SYMBIAN)

#include <aknedsts.h>
#include <coeaui.h>
#include <coemain.h>
#include <w32std.h>

#define EAknEditorFlagEnablePartialScreen 0x200000

#endif

...

#if defined(Q_OS_SYMBIAN)
    MCoeFepAwareTextEditor *fte = CCoeEnv::Static()->AppUi()->InputCapabilities().FepAwareTextEditor();

    // FepAwareTextEditor() returns 0 if no text editor is present
    if (fte)
    {
        CAknEdwinState *state = STATIC_CAST(CAknEdwinState*, fte->Extension1()->State(KNullUid));
        state->SetFlags(state->Flags() | EAknEditorFlagEnablePartialScreen);
    }
#endif

To make the linker happy, also a couple of libs must be added in the .pro file:

symbian:LIBS += -lcone -lws32 -lavkon -leikctl -leikcoctl -luiklaf -lform -lfepbase

After adding the stuff above the VKB now looks like this on a PR1.2 Nokia N8:

  

Split screen virtual keyboard in portrait and lanscape modes

Very simple, right? Well, there is a catch, or two. First of all, when the application starts and no text editors have been initialized, CCoeEnv::Static()->AppUi()->InputCapabilities().FepAwareTextEditor() returns 0, so we cannot just simply call that in the main() of our application. How I have done it is that I expose an enableSplitView() function that implements the functionality above to QML and call it in the onFocusChanged handler of the text editors. Since it’s only setting a flag this should be quite fast, albeit a bit of a hack.

Another bigger problem is that with this sort of a simple approach the QML UI has no knowledge of the whereabouts of the VKB. For example, if the text input field is at the bottom of the screen, it will get hidden behind the VKB once the VKB opens. One possibility would be to manually move the control to the top half of the screen when the VKB opens, but since there is no notification when the VKB is hidden, there’s no way to know when the view should be moved back to its original state. So in this very simple form the example is mostly usable only for the use cases where text input fields are already located in the top half of the screen.

The problems described above can most likely be fixed by making the implementation a bit more clever. Forum Nokia split view for Symbian applications wiki article shows how to handle KAknSplitInputEnabled and KAknSplitInputDisabled events in a Symbian C++ application, and I think that the same approach would work here as well. I.e. catch the events, forward them to QML and handle moving the view up or down based on the events. However, doing this might be risky and break in some weird way once Qt adds support for split screen VKB in 4.7.4. I think the very simple approach above should be relatively safe since it is only setting a state flag, but hacking deeper into Symbian land will easily cause problems in the future.

Which Qt version is installed?

Especially when working on a mobile environment (like Symbian), I seem to run into the same problem quite often – which version of Qt or Qt mobility do I have installed on this particular phone?

QtInfo running on Nokia N8 with Qt 4.7.3 from Qt SDK 1.1 RC installed

Lately I have been participating on a project called QtInfo which aims to provide a handy tool for digging out all sorts of information about the current Qt runtime environment. The mastermind behind the application is Attila Csipa, my contribution has been the part which digs out Qt Quick-related information:

  • supported Qt Quick version
  • list of installed Qt Quick plugins
  • list of available Qt Quick Components in case they have been installed.

The application has a lot of other functionality as well (see the project page), but in this blog post I’m concentrating on the stuff that I have implemented.

Figuring out the supported Qt Quick version is actually surprisingly difficult. The obvious solution would be of course to have a table of Qt versions and corresponding Qt Quick versions, but this wouldn’t be very future proof and might easily give wrong information. Our solution is to include a couple of QML files aimed at different Qt Quick versions with the application, try to parse them with QDeclarativeView and see which version the current Qt installation can parse without errors. Quite a rude method, but seems to work.

Similarly listing installed Qt Quick plugins is implemented with a bit of a brute force approach. Once the application has retrieved the import path info from QDeclarativeEngine, it goes through all the subdirectories in the import path. If a directory contains qmldir file, the application concludes that the directory contains a plugin, does a little path cleanup, ‘/’->’.’ conversions and that’s it, we got a plugin name. Like magic.

Qt Quick information, showing supported Qt Quick version, installed Qt Quick plugins and Qt Quick components

If the plugin name happens to be one of the known Qt Quick Components plugins (com.nokia.symbian, qt.labs.components etc) the application also parses the qmldir file to get a list of components that the plugin in question supports. Qt Quick Components are of course quite heavily under development at the moment, let’s see if this approach gets broken at some point, hopefully not.

Check out the project page and try the app out on your Maemo/Symbian device: https://projects.forum.nokia.com/qtinfo

Coloring Book with Qt Quick

Here’s something for your kids (or your inner kid). We recently had a team event which included a competition for creating an application with Qt Quick. Our group’s entry was a Coloring Book game:

Main view with amazingly stylish colors


The application turned out to be quite good so we decided to make it a public project in projects.forum.nokia.com, check out the project page at https://projects.forum.nokia.com/QtQuickColouringBook. Alternatively, you can just watch the video below to see how it looks and works:

The application has a couple of nice features, at least from technical point of view:

  • A custom QML ColoringCanvas element which does a simple flood fill when tapped.
  • Pinch zooming in the ColoringCanvas. For this I took the PinchArea implementation from Qt Quick 1.1, did some tidying up for the code to make it compile without any of the internal Qt stuff and included it in the project.
  • Enablers for purchasing new collections of images using the In-Application Purchasing API. This is not finalized though, and thus not enabled.

At the moment the application supports only Symbian^3. The reason for this is that the only way to zoom is by pinching, and since there is no support for multitouch in Symbian^1 devices or N900 coloring smaller areas would be quite impossible. Later we might implement something like double tap zooming for non-multitouch devices. Another problem is that currently the UI is hard-coded for 640×360 resolution, so adding support for e.g. N900 will require a bit of additional effort on the UI side.

I also made a simple dialog implementation for the project, which I might want to add this to the QML UI templates project as well at some point. Here’s how a dialog looks like, with nice dimmed background:

Color dialog


Another example of dialog usage is the file chooser:

Dialog for choosing the image


It still amazes me how quickly you can create a pretty good (and, more importantly, reasonably polished) looking application with Qt Quick. Getting the Coloring Book application to a state it is in now has taken around two days of coding (I did the visible stuff and the other dude has been working on the In App purchasing part and Symbian packaging magic). I’m not saying that the same application couldn’t be implemented easily with some other technology, but Qt Quick is definitely providing me with everything I need to get the UI that I have in my head implemented with minimal fuss. Of course the graphics etc. could be better, but that’s just my personal inability in graphical design, not the tools. :)

Note that at the moment we are not providing installation binaries for the application. Once Qt 4.7 is supported by the Smart Installer we are going to make installation files available at least for Symbian. The project compiles without trouble on Qt SDK 1.1 beta though, so it should be easy enough to try it out.

Follow

Get every new post delivered to your Inbox.