Skip to content

Commit 6ab1aa7

Browse files
committedSep 11, 2018
Add QgsThreadingUtils::runOnMainThread
1 parent e192e18 commit 6ab1aa7

File tree

5 files changed

+77
-48
lines changed

5 files changed

+77
-48
lines changed
 

‎src/analysis/vector/geometry_checker/qgsgeometrycheck.cpp

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,7 @@
1919
#include "qgsfeaturepool.h"
2020
#include "qgsvectorlayer.h"
2121
#include "qgsreadwritelocker.h"
22-
23-
template <typename Func>
24-
void runOnMainThread( const Func &func )
25-
{
26-
#if QT_VERSION >= QT_VERSION_CHECK( 5, 10, 0 )
27-
// Make sure we only deal with the vector layer on the main thread where it lives.
28-
// Anything else risks a crash.
29-
if ( QThread::currentThread() == qApp->thread() )
30-
func();
31-
else
32-
QMetaObject::invokeMethod( qApp, func, Qt::BlockingQueuedConnection );
33-
#else
34-
func();
35-
#endif
36-
}
22+
#include "qgsthreadingutils.h"
3723

3824
QgsGeometryCheckerContext::QgsGeometryCheckerContext( int _precision, const QgsCoordinateReferenceSystem &_mapCrs, const QMap<QString, QgsFeaturePool *> &_featurePools, const QgsCoordinateTransformContext &transformContext )
3925
: tolerance( std::pow( 10, -_precision ) )
@@ -50,7 +36,7 @@ const QgsCoordinateTransform &QgsGeometryCheckerContext::layerTransform( const Q
5036
if ( !mTransformCache.contains( layer ) )
5137
{
5238
QgsCoordinateTransform transform;
53-
runOnMainThread( [this, &transform, layer]()
39+
QgsThreadingUtils::runOnMainThread( [this, &transform, layer]()
5440
{
5541
QgsVectorLayer *lyr = layer.data();
5642
if ( lyr )
@@ -70,7 +56,7 @@ double QgsGeometryCheckerContext::layerScaleFactor( const QPointer<QgsVectorLaye
7056
if ( !mScaleFactorCache.contains( layer ) )
7157
{
7258
double scaleFactor = 1.0;
73-
runOnMainThread( [this, layer, &scaleFactor]()
59+
QgsThreadingUtils::runOnMainThread( [this, layer, &scaleFactor]()
7460
{
7561
QgsVectorLayer *lyr = layer.data();
7662
if ( lyr )

‎src/analysis/vector/geometry_checker/qgsvectordataproviderfeaturepool.cpp

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,10 @@ email : matthias@opengis.ch
1414
***************************************************************************/
1515

1616
#include "qgsvectordataproviderfeaturepool.h"
17+
#include "qgsthreadingutils.h"
1718

1819
#include "qgsfeaturerequest.h"
1920

20-
template <typename Func>
21-
void runOnMainThread( const Func &func )
22-
{
23-
#if QT_VERSION >= QT_VERSION_CHECK( 5, 10, 0 )
24-
// Make sure we only deal with the vector layer on the main thread where it lives.
25-
// Anything else risks a crash.
26-
if ( QThread::currentThread() == qApp->thread() )
27-
func();
28-
else
29-
QMetaObject::invokeMethod( qApp, func, Qt::BlockingQueuedConnection );
30-
#else
31-
func();
32-
#endif
33-
}
34-
3521
QgsVectorDataProviderFeaturePool::QgsVectorDataProviderFeaturePool( QgsVectorLayer *layer, bool selectedOnly )
3622
: QgsFeaturePool( layer )
3723
, mSelectedOnly( selectedOnly )
@@ -77,15 +63,15 @@ bool QgsVectorDataProviderFeaturePool::addFeature( QgsFeature &feature, Flags fl
7763
res = lyr->dataProvider()->addFeatures( features );
7864
};
7965

80-
runOnMainThread( addFeatureSynchronized );
66+
QgsThreadingUtils::runOnMainThread( addFeatureSynchronized );
8167

8268
if ( !res )
8369
return false;
8470

8571
feature.setId( features.front().id() );
8672
if ( mSelectedOnly )
8773
{
88-
runOnMainThread( [ this, feature ]()
74+
QgsThreadingUtils::runOnMainThread( [ this, feature ]()
8975
{
9076
QgsVectorLayer *lyr = layer();
9177
if ( lyr )
@@ -115,14 +101,14 @@ bool QgsVectorDataProviderFeaturePool::addFeatures( QgsFeatureList &features, Qg
115101
res = lyr->dataProvider()->addFeatures( features );
116102
};
117103

118-
runOnMainThread( addFeatureSynchronized );
104+
QgsThreadingUtils::runOnMainThread( addFeatureSynchronized );
119105

120106
if ( !res )
121107
return false;
122108

123109
if ( mSelectedOnly )
124110
{
125-
runOnMainThread( [ this, features ]()
111+
QgsThreadingUtils::runOnMainThread( [ this, features ]()
126112
{
127113
QgsVectorLayer *lyr = layer();
128114
if ( lyr )
@@ -156,7 +142,7 @@ void QgsVectorDataProviderFeaturePool::updateFeature( QgsFeature &feature )
156142
}
157143
changedAttributesMap.insert( feature.id(), attribMap );
158144

159-
runOnMainThread( [this, geometryMap, changedAttributesMap]()
145+
QgsThreadingUtils::runOnMainThread( [this, geometryMap, changedAttributesMap]()
160146
{
161147
QgsVectorLayer *lyr = layer();
162148
if ( lyr )
@@ -172,7 +158,7 @@ void QgsVectorDataProviderFeaturePool::updateFeature( QgsFeature &feature )
172158
void QgsVectorDataProviderFeaturePool::deleteFeature( QgsFeatureId fid )
173159
{
174160
removeFeature( fid );
175-
runOnMainThread( [this, fid]()
161+
QgsThreadingUtils::runOnMainThread( [this, fid]()
176162
{
177163
QgsVectorLayer *lyr = layer();
178164
if ( lyr )

‎src/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -946,6 +946,7 @@ SET(QGIS_CORE_HDRS
946946
qgstextlabelfeature.h
947947
qgstextrenderer.h
948948
qgstextrenderer_p.h
949+
qgsthreadingutils.h
949950
qgstracer.h
950951
qgstranslationcontext.h
951952

‎src/core/qgsthreadingutils.h

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/***************************************************************************
2+
qgsthreadingutils.h
3+
--------------------------------------
4+
Date : 11.9.2018
5+
Copyright : (C) 2018 by Matthias Kuhn
6+
email : matthias@opengis.ch
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#ifndef QGSTHREADINGUTILS_H
17+
#define QGSTHREADINGUTILS_H
18+
19+
#define SIP_NO_FILE
20+
21+
#include "qgis_core.h"
22+
23+
#include <QThread>
24+
25+
/**
26+
* \ingroup core
27+
* Provides threading utilities for QGIS.
28+
*/
29+
class CORE_EXPORT QgsThreadingUtils
30+
{
31+
public:
32+
33+
/**
34+
* Guarantees that \a func is executed on the main thread. If this is called
35+
* from another thread, the other thread will be blocked until the function
36+
* has been executed.
37+
* This is useful to quickly access information from objects that live on the
38+
* main thread and copying this information into worker threads. Avoid running
39+
* expensive code inside \a func.
40+
*
41+
* \note Only works with Qt >= 5.10, earlier versions will execute the code
42+
* in the worker thread.
43+
*
44+
* \since QGIS 3.4
45+
*/
46+
template <typename Func>
47+
static void runOnMainThread( const Func &func )
48+
{
49+
#if QT_VERSION >= QT_VERSION_CHECK( 5, 10, 0 )
50+
// Make sure we only deal with the vector layer on the main thread where it lives.
51+
// Anything else risks a crash.
52+
if ( QThread::currentThread() == qApp->thread() )
53+
func();
54+
else
55+
QMetaObject::invokeMethod( qApp, func, Qt::BlockingQueuedConnection );
56+
#else
57+
func();
58+
#endif
59+
}
60+
61+
};
62+
63+
64+
#endif

‎src/core/qgsvectorlayerutils.cpp

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "qgsrelationmanager.h"
2525
#include "qgsfeedback.h"
2626
#include "qgsvectorlayer.h"
27+
#include "qgsthreadingutils.h"
2728

2829
QgsFeatureIterator QgsVectorLayerUtils::getValuesIterator( const QgsVectorLayer *layer, const QString &fieldOrExpression, bool &ok, bool selectedOnly )
2930
{
@@ -516,16 +517,7 @@ std::unique_ptr<QgsVectorLayerFeatureSource> QgsVectorLayerUtils::getFeatureSour
516517
}
517518
};
518519

519-
#if QT_VERSION >= QT_VERSION_CHECK( 5, 10, 0 )
520-
// Make sure we only deal with the vector layer on the main thread where it lives.
521-
// Anything else risks a crash.
522-
if ( QThread::currentThread() == qApp->thread() )
523-
getFeatureSource();
524-
else
525-
QMetaObject::invokeMethod( qApp, getFeatureSource, Qt::BlockingQueuedConnection );
526-
#else
527-
getFeatureSource();
528-
#endif
520+
QgsThreadingUtils::runOnMainThread( getFeatureSource );
529521

530522
return featureSource;
531523
}

0 commit comments

Comments
 (0)
Please sign in to comment.