Namespaces

Variants
Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

Revision as of 19:02, 5 December 2013 by kiran10182 (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Group My Pictures for Symbian - app showcase

From Wiki
Jump to: navigation, search

Group My Pictures is application made to collect images in phone to one bigger image. This article explains the main aspects of the app's design and implementation.

Article Metadata
Code Example
Source file: Groupmypictures.zip
Tested with
SDK: Qt SDK 1.2
Devices(s): N8-00 Belle, C7
Compatibility
Platform(s):
Symbian
Article
Created: jupaavola (12 Mar 2012)
Last edited: kiran10182 (05 Dec 2013)

Contents

Introduction

Gmp icon2.png

Group My Pictures is application made to collect images in phone to one bigger image. Images can be set on different sheet shapes; square which contains images in 2 by 2 form, running slides from left to right or up to down. Before creating the resulting image, it is possible to change images position with drag and dropping. So just select pictures, drag them to right position and create picture group.


Summary

Most of this application is made with QML but JavaScript and Qt C++ are also used where appropriate.

The main application is quite heavy to load - it doesn't come up instantly, there is delay and it looks like nothing is happening. Solution is to load light splashscreen and in the background load main application. For this, we need two application viewers which are in same class what is created in main.cpp. And other where we need Qt coding is the image creation. It is just more simple and maybe slightly faster to use native code to combine several images to one, with scaling and other things of course.

But applications need settings, right? QSettings could be one way here, making wrapper class to expose it to QML but for this is used SQL database with JavaScript.

Design and flow

Splashscreen

Begin with splashscreen or shall we say loading screen. Here we need two application viewers, one to show splashscreen and other for main application. Main application itself is quite heavy to load, app should at least show it is doing something.

class Loader : public QObject
{
private slots:
void onStatusChanged(QDeclarativeView::Status status);
 
private:
QmlApplicationViewer viewer;
QmlApplicationViewer mainapp;
};

And then in loader class constructor create application viewers as normal and connect main application viewers statusChanged signal to loader.

viewer.setOrientation(QmlApplicationViewer::ScreenOrientationLockPortrait);
mainapp.setOrientation(QmlApplicationViewer::ScreenOrientationLockPortrait);
viewer.setMainQmlFile(QLatin1String("qml/groupmypictures/Splashscreen.qml"));
viewer.showExpanded();
connect(&mainapp,SIGNAL(statusChanged(QDeclarativeView::Status)),this,SLOT(onStatusChanged(QDeclarativeView::Status)));
mainapp.setMainQmlFile(QLatin1String("qml/groupmypictures/main.qml"));

When main application is finally loaded, it will signal us and then finally can show the real application itself

if(status == QDeclarativeView::Ready){
viewer.close();
mainapp.showExpanded();
}

Settings

SQLite and JavaScript, work hand in hand, also easy to use from QML. And what need to store is just few numbers and string. Actually numbers are enum's in image creation class, but still those are just plain numbers. But when application is run first time, there is no any database and no any content. Create default ones:

Import "Settings.js" as Settings
 
Component.onCompleted: {
Settings.initialize();
 
str = Settings.getSetting("imagesize");
if(str==="Unknown")
str = Settings.setSetting("imagesize",defaultImageSize);
 
str = Settings.getSetting("imagesize");
mainPage.imageSize = str
}

After creating default values, read values back and pass those to components which need them.

Image plugin

Plain QDeclarativeItem derived object. Combining pictures in Qt is simple, easy and fast. Although one could break asynchronous modeling with one invokable function what does all magic. So separate actual scaling and creation to thread owned by item class. Sametime we can keep up asynchronous running which means UI doesn't freeze when start scaling and painting. And also, creation can be stopped if wanted.

Other important is looking up storage where to save. Figure out what could be filename what to use, if creating lot of pictures, you don't want to write new name for every single file. So look files what there is, if founded file was for example gmp12032012.jpg, next one is gmp12032012_1.jpg. Pass it also to QML, as usual, to show what could be result filename. Drive storage, in here meaning more are we saving created images to internal or external memory. Internal memory here means phones mass memory, usually drive E. Drive C is smaller and can easily run out of space but like in N8, drive E is lot bigger so prefer that. External means memory cards, not any fancy thing here.

Then to the drawing, it is made by deriving QThread and using QPainter. Thread doesn't inform UI part in any way, all information is going through QDeclarativeItem class. And also, it is deleted always when it is not working. Example, creating image:

if(m_thread)
delete m_thread;
m_thread = new DrawThread(m_picturesHome,m_resolutions);
connect(m_thread,SIGNAL(finished()),this,SLOT(drawFinished()));
 
m_thread->createImage(m_imageType,m_imageSize,m_imageList,m_fileName,m_background,m_backgroundOld,m_margin);

In drawFinished() slot:

bool success = m_thread->success();
bool stopped = m_thread->stopRequested();
m_currentImage = QUrl::fromLocalFile(m_thread->filename());
delete m_thread;
m_thread = NULL;
if(!stopped){
emit imageFinished(success);
}else{
m_currentImage.clear();
emit canceled();
}

If we want to cancel thread, QThread's terminate is not good for now. Anyhow, thread would run to end and create image and eventually inform with terminated signal. So use member variable to check is thread allowed to run because this design were switch case and not while(forever) loop.

if(m_requestStop)
break;

QML

Main application starts with ListView to show what kind of shapes user can create. Due to bug, cannot use normal ListModel with ListElements with translationed texts. Translation, qsTr is treated as script and scripts not allowed in ListElements. Workaround is to create element as QtObject and model is list of QtObjects.

QtObject{
property string textSource
}
 
property list<QtObject> objectModel
 
ListView{
model: objectModel
}

Note that pages have all the time little popup help text. In gallery, it fades away and back automatically and in other views change text to shown. Small thing to make it even easier to use, no need to try and guess what to do.

Square differs from up to down and left to right views. In square view, it is used only GridView to show and edit resulting picture. But in other two, ListView is for preview and double tapping changes viewed item to GridView. Editing in all is using drag and dropping, nice feature of GridView component. MouseArea in GridView is changing index of images according to mouse presses, holding, releasing, etc. Delegate component X/Y coords are tied to GridView instead of delegate itself. And if in square mode there is choosed less than four images, empty ones are actually images also but painted with background color.

Finally when moving from preview to creation, application asks filename. Filename method is explained earlier in Image plugin and shown in here. Clicking button starts painter thread, dim screen and show BusyIndicator. And for a while, popup finished dialog where have option to open image or close. From both, dialog is dismissed and application returns to main view.

Demo video

The media player is loading...

Links

Note.pngNote: This is an entry in the Symbian Qt Quick Components Competition 2012Q1

This page was last modified on 5 December 2013, at 19:02.
465 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×