Map rendering: allow waiting for job while handling events

This commit is contained in:
Martin Dobias 2014-06-15 22:22:53 +07:00
parent 595f4efbb3
commit 9e3f921400
4 changed files with 39 additions and 1 deletions

View File

@ -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();

View File

@ -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 );
}
void QgsComposerMap::cache( void )

View File

@ -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;

View File

@ -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).
@ -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();