Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Map rendering: allow waiting for job while handling events
  • Loading branch information
wonder-sk committed Jun 15, 2014
1 parent 595f4ef commit 9e3f921
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 1 deletion.
14 changes: 14 additions & 0 deletions python/core/qgsmaprendererjob.sip
Expand Up @@ -204,6 +204,20 @@ class QgsMapRendererCustomPainterJob : QgsMapRendererJob
//! @note not available in python bindings
// const LayerRenderJobs& jobs() const { return mLayerJobs; }

/**
* Wait for the job to be finished - and keep the thread's event loop running while waiting.
*
* With a call to waitForFinished(), the waiting is done with a synchronization primitive
* and does not involve processing of messages. That may cause issues to code which requires
* some events to be handled in the main thread. Some plugins hooking into the rendering
* pipeline may require this in order to work properly - for example, OpenLayers plugin
* which uses a QWebPage in the main thread.
*
* Ideally the "wait for finished" method should not be used at all. The code triggering
* rendering should not need to actively wait for rendering to finish.
*/
void waitForFinishedWithEventLoop( QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents );

protected slots:
void futureFinished();

Expand Down
3 changes: 2 additions & 1 deletion src/core/composer/qgscomposermap.cpp
Expand Up @@ -222,7 +222,8 @@ void QgsComposerMap::draw( QPainter *painter, const QgsRectangle& extent, const
// render
QgsMapRendererCustomPainterJob job( jobMapSettings, painter );
job.start();
job.waitForFinished();
// wait, but allow network requests to be processed
job.waitForFinishedWithEventLoop( QEventLoop::ExcludeUserInputEvents );

This comment has been minimized.

Copy link
@nyalldawson

nyalldawson Jun 16, 2014

Collaborator

@wonder-sk I think this change has caused a regression - I now see a hang if I attempt to add a map item to a composition when a project has no layers in it.

This comment has been minimized.

Copy link
@wonder-sk

wonder-sk Jun 16, 2014

Author Member

Good catch - sorry for that. Should be fine again in bff7882

}

void QgsComposerMap::cache( void )
Expand Down
8 changes: 8 additions & 0 deletions src/core/qgsmaprendererjob.cpp
Expand Up @@ -297,6 +297,14 @@ QgsLabelingResults* QgsMapRendererCustomPainterJob::takeLabelingResults()
}


void QgsMapRendererCustomPainterJob::waitForFinishedWithEventLoop( QEventLoop::ProcessEventsFlags flags )
{
QEventLoop loop;
connect( &mFutureWatcher, SIGNAL( finished() ), &loop, SLOT( quit() ) );
loop.exec( flags );
}


void QgsMapRendererCustomPainterJob::futureFinished()
{
mActive = false;
Expand Down
15 changes: 15 additions & 0 deletions src/core/qgsmaprendererjob.h
Expand Up @@ -228,6 +228,7 @@ class CORE_EXPORT QgsMapRendererParallelJob : public QgsMapRendererQImageJob
};


#include <QEventLoop>

/** job implementation that renders everything sequentially using a custom painter.
* The returned image is always invalid (because there is none available).
Expand All @@ -248,6 +249,20 @@ class CORE_EXPORT QgsMapRendererCustomPainterJob : public QgsMapRendererJob
//! @note not available in python bindings
const LayerRenderJobs& jobs() const { return mLayerJobs; }

/**
* Wait for the job to be finished - and keep the thread's event loop running while waiting.
*
* With a call to waitForFinished(), the waiting is done with a synchronization primitive
* and does not involve processing of messages. That may cause issues to code which requires
* some events to be handled in the main thread. Some plugins hooking into the rendering
* pipeline may require this in order to work properly - for example, OpenLayers plugin
* which uses a QWebPage in the main thread.
*
* Ideally the "wait for finished" method should not be used at all. The code triggering
* rendering should not need to actively wait for rendering to finish.
*/
void waitForFinishedWithEventLoop( QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents );

protected slots:
void futureFinished();

Expand Down

0 comments on commit 9e3f921

Please sign in to comment.