Skip to content

Commit

Permalink
Ensure member QObjects for QgsMapLayer (and subclasses) are correctly
Browse files Browse the repository at this point in the history
parented to their owner QgsMapLayer.

This ensures that if the layer is moved to a different thread with
QObject::moveToThread(), then those children are also considered
by QObject::moveToThread() and correctly also moved to the new
target thread. This fixes broken connections (and likely other
issues) caused when moving layers between threads (such as is
done when a background processing algorithm completes).

Fixes #18005
  • Loading branch information
nyalldawson committed Feb 5, 2018
1 parent dbe45b8 commit 0607f79
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 2 deletions.
3 changes: 3 additions & 0 deletions src/core/qgsmaplayer.cpp
Expand Up @@ -1909,7 +1909,10 @@ void QgsMapLayer::setLegend( QgsMapLayerLegend *legend )
mLegend = legend;

if ( mLegend )
{
mLegend->setParent( this );
connect( mLegend, &QgsMapLayerLegend::itemsChanged, this, &QgsMapLayer::legendChanged );
}

emit legendChanged();
}
Expand Down
9 changes: 7 additions & 2 deletions src/core/qgsmaplayerstylemanager.h
Expand Up @@ -25,6 +25,7 @@ class QgsMapLayer;
#include <QObject>

#include "qgis_core.h"
#include "qgis_sip.h"

class QDomElement;

Expand Down Expand Up @@ -96,8 +97,12 @@ class CORE_EXPORT QgsMapLayerStyleManager : public QObject
{
Q_OBJECT
public:
//! Construct a style manager associated with a map layer (must not be null)
QgsMapLayerStyleManager( QgsMapLayer *layer );

/**
* Construct a style manager associated with a map layer (must not be null).
* The style manager will be parented to \a layer.
*/
QgsMapLayerStyleManager( QgsMapLayer *layer SIP_TRANSFERTHIS );

//! Get pointer to the associated map layer
QgsMapLayer *layer() const { return mLayer; }
Expand Down
3 changes: 3 additions & 0 deletions src/core/qgsvectorlayer.cpp
Expand Up @@ -147,6 +147,7 @@ QgsVectorLayer::QgsVectorLayer( const QString &vectorLayerPath,
mConditionalStyles = new QgsConditionalLayerStyles();

mJoinBuffer = new QgsVectorLayerJoinBuffer( this );
mJoinBuffer->setParent( this );
connect( mJoinBuffer, &QgsVectorLayerJoinBuffer::joinedFieldsChanged, this, &QgsVectorLayer::onJoinedFieldsChanged );

mExpressionFieldBuffer = new QgsExpressionFieldBuffer();
Expand Down Expand Up @@ -1553,6 +1554,7 @@ bool QgsVectorLayer::setDataProvider( QString const &provider )
return false;
}

mDataProvider->setParent( this );
connect( mDataProvider, &QgsVectorDataProvider::raiseError, this, &QgsVectorLayer::raiseError );

QgsDebugMsgLevel( QStringLiteral( "Instantiated the data provider plugin" ), 2 );
Expand Down Expand Up @@ -4405,6 +4407,7 @@ void QgsVectorLayer::setAuxiliaryLayer( QgsAuxiliaryLayer *alayer )
}

mAuxiliaryLayer.reset( alayer );
mAuxiliaryLayer->setParent( this );
updateFields();
}

Expand Down
1 change: 1 addition & 0 deletions src/core/raster/qgsrasterlayer.cpp
Expand Up @@ -614,6 +614,7 @@ void QgsRasterLayer::setDataProvider( QString const &provider )
return;
}
QgsDebugMsgLevel( "Data provider created", 4 );
mDataProvider->setParent( this );

// Set data provider into pipe even if not valid so that it is deleted with pipe (with layer)
mPipe.set( mDataProvider );
Expand Down

0 comments on commit 0607f79

Please sign in to comment.