Skip to content

Commit a5e33fa

Browse files
committed
Add method to take layer and ownership from a project
1 parent 9bb0762 commit a5e33fa

File tree

4 files changed

+61
-0
lines changed

4 files changed

+61
-0
lines changed

python/core/qgsproject.sip

+2
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,8 @@ class QgsProject : QObject, QgsExpressionContextGenerator
480480
*/
481481
void removeMapLayer( QgsMapLayer* layer );
482482

483+
QgsMapLayer *takeMapLayer( QgsMapLayer *layer ) /TransferBack/;
484+
483485
/**
484486
* Removes all registered layers. If the registry has ownership
485487
* of any layers these layers will also be deleted.

src/core/qgsproject.cpp

+21
Original file line numberDiff line numberDiff line change
@@ -2201,6 +2201,27 @@ void QgsProject::removeMapLayer( QgsMapLayer *layer )
22012201
removeMapLayers( QList<QgsMapLayer *>() << layer );
22022202
}
22032203

2204+
QgsMapLayer *QgsProject::takeMapLayer( QgsMapLayer *layer )
2205+
{
2206+
if ( !layer )
2207+
return nullptr;
2208+
2209+
if ( mMapLayers.contains( layer->id() ) )
2210+
{
2211+
emit layersWillBeRemoved( QStringList() << layer->id() );
2212+
emit layersWillBeRemoved( QList<QgsMapLayer *>() << layer );
2213+
emit layerWillBeRemoved( layer->id() );
2214+
emit layerWillBeRemoved( layer );
2215+
2216+
mMapLayers.remove( layer->id() );
2217+
layer->setParent( nullptr );
2218+
emit layerRemoved( layer->id() );
2219+
emit layersRemoved( QStringList() << layer->id() );
2220+
return layer;
2221+
}
2222+
return nullptr; //don't return layer - it wasn't owned and accordingly we aren't transferring ownership
2223+
}
2224+
22042225
void QgsProject::removeAllMapLayers()
22052226
{
22062227
emit removeAll();

src/core/qgsproject.h

+9
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,15 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera
699699
*/
700700
void removeMapLayer( QgsMapLayer *layer );
701701

702+
/**
703+
* Takes a layer from the registry. If the layer was owned by the project, the
704+
* layer will be returned without deleting it. The caller takes ownership of
705+
* the layer and is responsible for deleting it.
706+
* \see removeMapLayer()
707+
* \since QGIS 3.0
708+
*/
709+
QgsMapLayer *takeMapLayer( QgsMapLayer *layer );
710+
702711
/**
703712
* Removes all registered layers. If the registry has ownership
704713
* of any layers these layers will also be deleted.

tests/src/python/test_qgsmaplayerregistry.py

+29
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,35 @@ def test_RemoveLayerShouldNotSegFault(self):
502502
for k, layer in list(reg.mapLayers().items()):
503503
assert(layer is not None)
504504

505+
def testTakeLayer(self):
506+
# test taking ownership of a layer from the project
507+
l1 = createLayer('l1')
508+
l2 = createLayer('l2')
509+
p = QgsProject()
510+
511+
# add one layer to project
512+
p.addMapLayer(l1)
513+
self.assertEqual(p.mapLayers(), {l1.id(): l1})
514+
self.assertEqual(l1.parent(), p)
515+
516+
# try taking some layers which don't exist in project
517+
self.assertFalse(p.takeMapLayer(None))
518+
self.assertFalse(p.takeMapLayer(l2))
519+
# but l2 should still exist..
520+
self.assertTrue(l2.isValid())
521+
522+
# take layer from project
523+
self.assertEqual(p.takeMapLayer(l1), l1)
524+
self.assertFalse(p.mapLayers()) # no layers left
525+
# but l1 should still exist
526+
self.assertTrue(l1.isValid())
527+
# layer should have no parent now
528+
self.assertFalse(l1.parent())
529+
530+
# destroy project
531+
p = None
532+
self.assertTrue(l1.isValid())
533+
505534

506535
if __name__ == '__main__':
507536
unittest.main()

0 commit comments

Comments
 (0)