diff --git a/src/core/vector/qgsvectorlayer.cpp b/src/core/vector/qgsvectorlayer.cpp index c9900a72077..2cb95b6278e 100644 --- a/src/core/vector/qgsvectorlayer.cpp +++ b/src/core/vector/qgsvectorlayer.cpp @@ -2033,10 +2033,10 @@ void QgsVectorLayer::setDataSourcePrivate( const QString &dataSource, const QStr } // if the default style failed to load or was disabled use some very basic defaults - if ( !defaultLoadedFlag && isSpatial() ) + if ( !defaultLoadedFlag ) { - // add single symbol renderer - setRenderer( QgsFeatureRenderer::defaultRenderer( geometryType() ) ); + // add single symbol renderer for spatial layers + setRenderer( isSpatial() ? QgsFeatureRenderer::defaultRenderer( geometryType() ) : nullptr ); } if ( !mSetLegendFromStyle ) @@ -4179,7 +4179,10 @@ void QgsVectorLayer::setRenderer( QgsFeatureRenderer *r ) // we must allow setting a renderer if our geometry type is unknown // as this allows the renderer to be correctly set even for layers // with broken sources - if ( !isSpatial() && mWkbType != Qgis::WkbType::Unknown ) + // (note that we allow REMOVING the renderer for non-spatial layers, + // e.g. to permit removing the renderer when the layer changes from + // a spatial layer to a non-spatial one) + if ( r && !isSpatial() && mWkbType != Qgis::WkbType::Unknown ) return; if ( r != mRenderer ) diff --git a/tests/src/python/test_qgsvectorlayer.py b/tests/src/python/test_qgsvectorlayer.py index 51a73c9d772..bfc1341b324 100644 --- a/tests/src/python/test_qgsvectorlayer.py +++ b/tests/src/python/test_qgsvectorlayer.py @@ -374,6 +374,19 @@ class TestQgsVectorLayer(QgisTestCase, FeatureSourceTestCase): self.assertNotEqual(layer.renderer(), r) self.assertEqual(layer.renderer().symbol().type(), QgsSymbol.Fill) + # reset layer to a non-spatial layer + lines_path = os.path.join(unitTestDataPath(), 'nonspatial.dbf') + layer.setDataSource(lines_path, 'new name2', 'ogr', options) + + self.assertTrue(layer.isValid()) + self.assertEqual(layer.name(), 'new name2') + self.assertEqual(layer.wkbType(), QgsWkbTypes.NoGeometry) + self.assertFalse(layer.crs().isValid()) + self.assertIn('nonspatial.dbf', layer.dataProvider().dataSourceUri()) + self.assertEqual(len(spy), 3) + # should have REMOVED renderer + self.assertIsNone(layer.renderer()) + def testSetDataSourceInvalidToValid(self): """ Test that changing an invalid layer path to valid maintains the renderer