×
Namespaces

Variants
Actions
Revision as of 18:41, 27 May 2012 by hugovk (Talk | contribs)

How to add multithread support to your Qt application

From Nokia Developer Wiki
Jump to: navigation, search

Note.pngNote: This is an entry in the PureView Imaging Competition 2012Q2

Article Metadata
Tested with
Devices(s): Nokia C7-00, Nokia N8, Nokia N950
CompatibilityArticle
Keywords: Thread, QThread, QRunnable,QThreadPool
Created: galazzo (21 May 2012)
Last edited: hugovk (27 May 2012)

Contents

Introduction

This article explains how to manage multithreading in a mobile application. QHdrCamera will be used as a showcase.

Showcase

QHdrCamera is a component component able to create High Dynamic Range images.

Basically to do that the component captures three photos at different exposure range mixing them using some algorithms. For further information, please refer to this article.

Capturing images in sequence has to be done as fast as possible. Each time the QML component will be asked to shoot a frame it saves the captured image in the default path, after which it is ready to capture another frame.

After the process of capturing three images, the flow process need to load all three photo into memory for the raw image processing to produce our HDR image.

The loading process is very slow, especially as resolution grows, due to the (at time of writing, May 2012) phone memory speed, so this impacts the overall processing time. If, during shooting the next frame, the application was also able to begin loading the previously saved frame into memory this will reduce the waiting time, enhancing user experience.

The solution provided uses QRunnable interface and QThreadPool class.

QRunnable

The QRunnable class is an interface for representing a task or piece of code that needs to be executed, represented by your reimplementation of the run() function.

QThreadPool executes your code in a separate thread supporting execution of the same QRunnable more than once.

Multithread Image Loading

The first step is to implement the QRunnable interface:

class LoadingThread : public QRunnable
{
public:
LoadingThread(QString*, QImage*);
 
private:
QString* path;
QImage* image;
 
protected:
void run();
};
 
LoadingThread::LoadingThread(QString* path, QImage* image){
this->path = path;
this->image = image;
}
 
void LoadingThread::run() {
if( image->load(*path) ){
qDebug() << "Image loaded";
} else {
qDebug() << "Error during image loading " << *path;
}
}

QThreadPool

The QML Camera component provides the onImageSaved ( path ) signal, called after the image has been written to the filesystem, in this context connected to setShot slots. Here we create the LoadingThread to start memory loading process in the background.

void QHdrCamera::setShot1(QString path) {
if( !QFile::rename(path, QDir::toNativeSeparators(s_shot1)) ) {
qDebug() << "Impossible to rename shot1:" << path;
} else {
LoadingThread* tLoad = new LoadingThread(&s_shot1, &shot1);
QThreadPool::globalInstance()->start(tLoad);
emit savedShot1();
}
}
 
void QHdrCamera::setShot2(QString path) {
if( !QFile::rename(path, s_shot2) ) {
qDebug() << "Impossible to rename shot2";
} else {
LoadingThread* tLoad = new LoadingThread(&s_shot2, &shot2);
QThreadPool::globalInstance()->start(tLoad);
emit savedShot2();
}
}
 
void QHdrCamera::setShot3(QString path) {
if( !QFile::rename(path, s_shot3) ){
qDebug() << "Impossible to rename shot3";
} else {
LoadingThread* tLoad = new LoadingThread(&s_shot3, &shot3);
QThreadPool::globalInstance()->start(tLoad);
emit savedShot3();
}
}

The application has to wait until all threads finish their jobs. QThreadPool provides a method called waitForDone()' that does that.

QThreadPool::globalInstance()->waitForDone();
247 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.

×