Skip to content
Permalink
Browse files

Try (and fail) to avoid a qApp->processEvents() call

I just can't find any other reliable way to wait until javascript
execution in a web page has completed.
  • Loading branch information
nyalldawson committed Dec 28, 2017
1 parent 88a8390 commit 8de8bb387f2969ea3e2132bb16cf7bfe87acfaba
@@ -261,6 +261,7 @@ Recalculates the frame sizes for the current viewport dimensions

};


/************************************************************************
* This file has been generated automatically from *
* *
@@ -197,9 +197,12 @@ void QgsLayoutItemHtml::loadHtml( const bool useCache, const QgsExpressionContex
//inject JSON feature
if ( !mAtlasFeatureJSON.isEmpty() )
{
mWebPage->mainFrame()->evaluateJavaScript( QStringLiteral( "if ( typeof setFeature === \"function\" ) { setFeature(%1); }" ).arg( mAtlasFeatureJSON ) );
//needs an extra process events here to give JavaScript a chance to execute
qApp->processEvents();
JavascriptExecutorLoop jsLoop;

mWebPage->mainFrame()->addToJavaScriptWindowObject( "loop", &jsLoop );
mWebPage->mainFrame()->evaluateJavaScript( QStringLiteral( "if ( typeof setFeature === \"function\" ) { setFeature(%1); }; loop.done();" ).arg( mAtlasFeatureJSON ) );

jsLoop.execIfNotDone();
}

recalculateFrameSizes();
@@ -533,3 +536,25 @@ void QgsLayoutItemHtml::refreshDataDefinedProperty( const QgsLayoutObject::DataD
loadHtml( true, &context );
}
}

//JavascriptExecutorLoop
///@cond PRIVATE

void JavascriptExecutorLoop::done()
{
mDone = true;
quit();
}

void JavascriptExecutorLoop::execIfNotDone()
{
if ( !mDone )
exec( QEventLoop::ExcludeUserInputEvents );

// gross, but nothing else works, so f*** it.. it's not worth spending a day trying to find a non-hacky way
// to force the web page to update following the js execution
for ( int i = 0; i < 100; i++ )
qApp->processEvents();
}

///@endcond
@@ -276,4 +276,22 @@ class CORE_EXPORT QgsLayoutItemHtml: public QgsLayoutMultiFrame
void refreshExpressionContext();
};

///@cond PRIVATE
#ifndef SIP_RUN
class JavascriptExecutorLoop : public QEventLoop
{
Q_OBJECT
public slots:

void done();
void execIfNotDone();

private:

bool mDone = false;

};
#endif
///@endcond

#endif // QGSLAYOUTITEMHTML_H

0 comments on commit 8de8bb3

Please sign in to comment.
You can’t perform that action at this time.