Skip to content

Commit 291224e

Browse files
committedAug 16, 2018
[wfs] Avoid widget access from non main thread
It's not safe to loop through the app's widgets in a background thread, so defer determination of the main window until the progress dialog is being created in the main thread
1 parent 3b861f2 commit 291224e

File tree

2 files changed

+24
-11
lines changed

2 files changed

+24
-11
lines changed
 

‎src/providers/wfs/qgswfsfeatureiterator.cpp

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,28 @@ void QgsWFSFeatureDownloader::hideProgressDialog()
156156
// Called from GUI thread
157157
void QgsWFSFeatureDownloader::createProgressDialog()
158158
{
159+
Q_ASSERT( qApp->thread() == QThread::currentThread() );
160+
159161
if ( mStop )
160162
return;
161163
Q_ASSERT( !mProgressDialog );
164+
165+
if ( !mMainWindow )
166+
{
167+
const QWidgetList widgets = qApp->topLevelWidgets();
168+
for ( QWidget *widget : widgets )
169+
{
170+
if ( widget->objectName() == QLatin1String( "QgisApp" ) )
171+
{
172+
mMainWindow = widget;
173+
break;
174+
}
175+
}
176+
}
177+
178+
if ( !mMainWindow )
179+
return;
180+
162181
mProgressDialog = new QgsWFSProgressDialog( tr( "Loading features for layer %1" ).arg( mShared->mURI.typeName() ),
163182
tr( "Abort" ), 0, mNumberMatched, mMainWindow );
164183
mProgressDialog->setWindowTitle( tr( "QGIS" ) );
@@ -430,17 +449,10 @@ void QgsWFSFeatureDownloader::run( bool serializeFeatures, int maxFeatures )
430449

431450
if ( !mShared->mHideProgressDialog && maxFeatures != 1 && mShared->supportsHits() )
432451
{
433-
Q_FOREACH ( QWidget *widget, qApp->topLevelWidgets() )
434-
{
435-
if ( widget->objectName() == QLatin1String( "QgisApp" ) )
436-
{
437-
mMainWindow = widget;
438-
break;
439-
}
440-
}
452+
mUseProgressDialog = true;
441453
}
442454

443-
if ( mMainWindow )
455+
if ( mUseProgressDialog )
444456
{
445457
// In case the header of the GetFeature response doesn't contain the total
446458
// number of features, or we don't get it within 4 seconds, we will issue
@@ -586,7 +598,7 @@ void QgsWFSFeatureDownloader::run( bool serializeFeatures, int maxFeatures )
586598

587599
// Consider if we should display a progress dialog
588600
// We can only do that if we know how many features will be downloaded
589-
if ( !mTimer && maxFeatures != 1 && mMainWindow )
601+
if ( !mTimer && maxFeatures != 1 && mUseProgressDialog )
590602
{
591603
if ( mNumberMatched < 0 )
592604
{
@@ -626,7 +638,7 @@ void QgsWFSFeatureDownloader::run( bool serializeFeatures, int maxFeatures )
626638
// thread of this
627639
connect( mTimer, &QTimer::timeout, this, &QgsWFSFeatureDownloader::createProgressDialog, Qt::DirectConnection );
628640

629-
mTimer->moveToThread( mMainWindow->thread() );
641+
mTimer->moveToThread( qApp->thread() );
630642
QMetaObject::invokeMethod( mTimer, "start", Qt::QueuedConnection );
631643
}
632644
}

‎src/providers/wfs/qgswfsfeatureiterator.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ class QgsWFSFeatureDownloader: public QgsWfsRequest
153153
int mPageSize;
154154
bool mRemoveNSPrefix;
155155
int mNumberMatched;
156+
bool mUseProgressDialog = false;
156157
QWidget *mMainWindow = nullptr;
157158
QTimer *mTimer = nullptr;
158159
QgsWFSFeatureHitsAsyncRequest mFeatureHitsAsyncRequest;

0 commit comments

Comments
 (0)
Please sign in to comment.