class TestQgsLayerTreeView(unittest.TestCase): def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) # setup a dummy project self.project = QgsProject() self.layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory") self.layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2", "memory") self.layer3 = QgsVectorLayer("Point?field=fldtxt:string", "layer3", "memory") self.project.addMapLayers([self.layer, self.layer2, self.layer3]) self.model = QgsLayerTreeModel(self.project.layerTreeRoot()) def testSetModel(self): view = QgsLayerTreeView() # should not work string_list_model = QStringListModel() view.setModel(string_list_model) self.assertFalse(view.model()) # should work view.setModel(self.model) self.assertEqual(view.model(), self.model) def testSetCurrentLayer(self): view = QgsLayerTreeView() view.setModel(self.model) current_layer_changed_spy = QSignalSpy(view.currentLayerChanged) self.assertFalse(view.currentLayer()) view.setCurrentLayer(self.layer3) self.assertEqual(view.currentLayer(), self.layer3) self.assertEqual(len(current_layer_changed_spy), 1) view.setCurrentLayer(self.layer) self.assertEqual(view.currentLayer(), self.layer) self.assertEqual(len(current_layer_changed_spy), 2) view.setCurrentLayer(None) self.assertFalse(view.currentLayer()) self.assertEqual(len(current_layer_changed_spy), 3) def testDefaultActions(self): view = QgsLayerTreeView() view.setModel(self.model) actions = QgsLayerTreeViewDefaultActions(view) # show in overview action view.setCurrentLayer(self.layer) self.assertEqual(view.currentNode().customProperty('overview', 0), False) show_in_overview = actions.actionShowInOverview() show_in_overview.trigger() self.assertEqual(view.currentNode().customProperty('overview', 0), True) show_in_overview.trigger() self.assertEqual(view.currentNode().customProperty('overview', 0), False)
def test_project_server_validator(self): """Test project server validator.""" project = QgsProject() layer = QgsVectorLayer('Point?field=fldtxt:string', 'layer_1', 'memory') project.addMapLayers([layer]) # Valid valid, results = QgsProjectServerValidator.validate(project) self.assertTrue(valid) self.assertFalse(results) layer_1 = QgsVectorLayer('Point?field=fldtxt:string', 'layer_1', 'memory') project.addMapLayers([layer_1]) # Not valid, same layer name valid, results = QgsProjectServerValidator.validate(project) self.assertFalse(valid) self.assertEqual(1, len(results)) self.assertEqual(QgsProjectServerValidator.DuplicatedNames, results[0].error) # Not valid, short name is invalid layer_1.setShortName('layer_1_invalid_#') valid, results = QgsProjectServerValidator.validate(project) self.assertFalse(valid) self.assertEqual(1, len(results)) self.assertEqual(QgsProjectServerValidator.ShortNames, results[0].error) # Not valid, same short name as the first layer name layer_1.setShortName('layer_1') valid, results = QgsProjectServerValidator.validate(project) self.assertFalse(valid) self.assertEqual(1, len(results)) self.assertEqual(QgsProjectServerValidator.DuplicatedNames, results[0].error) # Valid layer_1.setShortName('layer_1_bis') valid, results = QgsProjectServerValidator.validate(project) self.assertTrue(valid) self.assertEqual(0, len(results)) # Not valid, a group with same name as the first layer group = project.layerTreeRoot().addGroup('layer_1') valid, results = QgsProjectServerValidator.validate(project) self.assertFalse(valid) self.assertEqual(1, len(results)) self.assertEqual(QgsProjectServerValidator.DuplicatedNames, results[0].error) # Valid group.setCustomProperty('wmsShortName', 'my_group1') valid, results = QgsProjectServerValidator.validate(project) self.assertTrue(valid) self.assertEqual(0, len(results))
def test_layer_order_with_group_layer(self): """ Test retrieving layer order with group layers present """ p = QgsProject() layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory") p.addMapLayer(layer, False) layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2", "memory") p.addMapLayer(layer2, False) layer3 = QgsVectorLayer("Point?field=fldtxt:string", "layer3", "memory") p.addMapLayer(layer3, False) layer4 = QgsVectorLayer("Point?field=fldtxt:string", "layer4", "memory") p.addMapLayer(layer4, False) p.layerTreeRoot().addLayer(layer) group_node = p.layerTreeRoot().addGroup('my group') group_node.addLayer(layer2) group_node.addLayer(layer3) p.layerTreeRoot().addLayer(layer4) self.assertEqual(p.layerTreeRoot().layerOrder(), [layer, layer2, layer3, layer4]) options = QgsGroupLayer.LayerOptions(QgsCoordinateTransformContext()) group_layer = group_node.convertToGroupLayer(options) p.addMapLayer(group_layer, False) self.assertEqual(p.layerTreeRoot().layerOrder(), [layer, group_layer, layer4]) self.assertEqual(group_layer.childLayers(), [layer3, layer2])
def test_json_export(self): project = QgsProject() self.assertTrue(project.read(os.path.join(unitTestDataPath('qgis_server'), 'test_project.qgs'))) model = QgsLegendModel(project.layerTreeRoot()) ctx = QgsRenderContext() settings = QgsLegendSettings() renderer = QgsLegendRenderer(model, settings) nodes = renderer.exportLegendToJson(ctx)['nodes'].toVariant() self.assertEqual(len(nodes), 7) self.assertEqual(nodes[0]['type'], 'layer') self.assertEqual(nodes[0]['title'], 'testlayer')
def create(self, qgis_project: QgsProject, group=None): if not group: group = qgis_project.layerTreeRoot() existing_layer_source_uris = [ found_layer.layer().dataProvider().dataSourceUri() for found_layer in qgis_project.layerTreeRoot().findLayers() ] static_index = 0 for item in self.items: if isinstance(item, LegendGroup): subgroup = group.findGroup(item.name) if subgroup is None: subgroup = group.addGroup(item.name) item.create(qgis_project, subgroup) subgroup.setExpanded(item.expanded) subgroup.setItemVisibilityChecked(item.checked) subgroup.setIsMutuallyExclusive(item.mutually_exclusive, item.mutually_exclusive_child) else: layer = item.layer if (layer.dataProvider().dataSourceUri() not in existing_layer_source_uris): if self.static_sorting: index = static_index elif layer.isSpatial(): index = get_suggested_index_for_layer( layer, group, self.ignore_node_names) else: index = 0 layernode = QgsLayerTreeLayer(layer) layernode.setExpanded(item.expanded) layernode.setItemVisibilityChecked(item.checked) layernode.setCustomProperty("showFeatureCount", item.featurecount) group.insertChildNode(index, layernode) static_index += 1
def test_restore_group_node_group_layer(self): """ Test that group node's QgsGroupLayers are restored with projects """ p = QgsProject() layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory") p.addMapLayer(layer, False) layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2", "memory") p.addMapLayer(layer2, False) group_node = p.layerTreeRoot().addGroup('my group') group_node.addLayer(layer) group_node.addLayer(layer2) options = QgsGroupLayer.LayerOptions(QgsCoordinateTransformContext()) group_layer = group_node.convertToGroupLayer(options) p.addMapLayer(group_layer, False) with TemporaryDirectory() as d: path = os.path.join(d, 'group_layers.qgs') p.setFileName(path) p.write() p2 = QgsProject() p2.read(path) restored_group_node = p2.layerTreeRoot().children()[0] self.assertEqual(restored_group_node.name(), 'my group') restored_group_layer = restored_group_node.groupLayer() self.assertIsNotNone(restored_group_layer) self.assertEqual(restored_group_layer.childLayers()[0].name(), 'layer2') self.assertEqual(restored_group_layer.childLayers()[1].name(), 'layer1')
def _get_group( *, project: qgc.QgsProject, group_path: tuple[str, ...], ) -> qgc.QgsLayerTreeGroup: # Starting at the root of the layer tree, climb the tree until we reach the # parent of group_node. group = project.layerTreeRoot() for group_name in group_path: group = group.findGroup(group_name) if not group: raise exc.QgrQgsLayerTreeGroupError( f'Unable to find group {group_path}.', ) return group
def create(self, qgis_project: QgsProject, group=None): if not group: group = qgis_project.layerTreeRoot() for item in self.items: if isinstance(item, LegendGroup): subgroup = group.findGroup(item.name) if subgroup is None: subgroup = group.addGroup(item.name) subgroup.setExpanded(item.expanded) item.create(qgis_project, subgroup) else: layer = item.layer index = get_suggested_index_for_layer(layer, group) if layer.isSpatial() else 0 group.insertLayer(index, layer)
def testEmbeddedGroup(self): testdata_path = unitTestDataPath('embedded_groups') + '/' prj_path = os.path.join(testdata_path, "project2.qgs") prj = QgsProject() prj.read(prj_path) layer_tree_group = prj.layerTreeRoot() self.assertEqual(len(layer_tree_group.findLayerIds()), 2) for layer_id in layer_tree_group.findLayerIds(): name = prj.mapLayer(layer_id).name() self.assertTrue(name in ['polys', 'lines']) if name == 'polys': self.assertTrue(layer_tree_group.findLayer(layer_id).itemVisibilityChecked()) elif name == 'lines': self.assertFalse(layer_tree_group.findLayer(layer_id).itemVisibilityChecked())
def testEmbeddedGroup(self): testdata_path = unitTestDataPath('embedded_groups') + '/' prj_path = os.path.join(testdata_path, "project2.qgs") prj = QgsProject() prj.read(prj_path) layer_tree_group = prj.layerTreeRoot() layers_ids = layer_tree_group.findLayerIds() layers_names = [] for layer_id in layers_ids: name = prj.mapLayer(layer_id).name() layers_names.append(name) expected = ['polys', 'lines'] self.assertEqual(sorted(layers_names), sorted(expected))
def create(self, qgis_project: QgsProject, group=None): if not group: group = qgis_project.layerTreeRoot() for item in self.items: if isinstance(item, LegendGroup): subgroup = get_group_non_recursive(group, item.name) if subgroup is None: # If the subgroup does not exist or it's not child of root subgroup = group.addGroup(item.name) subgroup.setExpanded(item.expanded) item.create(qgis_project, subgroup) else: layer = item.layer index = get_suggested_index_for_layer( layer, group, self.ignore_node_names) if layer.isSpatial() else 0 group.insertLayer(index, layer)
def testEmbeddedGroup(self): testdata_path = unitTestDataPath('embedded_groups') + '/' prj_path = os.path.join(testdata_path, "project2.qgs") prj = QgsProject() prj.read(prj_path) layer_tree_group = prj.layerTreeRoot() self.assertEqual(len(layer_tree_group.findLayerIds()), 2) for layer_id in layer_tree_group.findLayerIds(): name = prj.mapLayer(layer_id).name() self.assertTrue(name in ['polys', 'lines']) if name == 'polys': self.assertTrue( layer_tree_group.findLayer( layer_id).itemVisibilityChecked()) elif name == 'lines': self.assertFalse( layer_tree_group.findLayer( layer_id).itemVisibilityChecked())
class TestQgsLayerTreeView(unittest.TestCase): def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) # setup a dummy project self.project = QgsProject() self.layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory") self.layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2", "memory") self.layer3 = QgsVectorLayer("Point?field=fldtxt:string", "layer3", "memory") self.layer4 = QgsVectorLayer("Point?field=fldtxt:string", "layer4", "memory") self.layer5 = QgsVectorLayer("Point?field=fldtxt:string", "layer5", "memory") self.project.addMapLayers([self.layer, self.layer2, self.layer3]) self.model = QgsLayerTreeModel(self.project.layerTreeRoot()) def nodeOrder(self, group): nodeorder = [] layerTree = QgsLayerTree() for node in group: if QgsLayerTree.isGroup(node): groupname = node.name() nodeorder.append(groupname) for child in self.nodeOrder(node.children()): nodeorder.append(groupname + '-' + child) elif QgsLayerTree.isLayer(node): nodeorder.append(node.layer().name()) return nodeorder def testSetModel(self): view = QgsLayerTreeView() # should not work string_list_model = QStringListModel() view.setModel(string_list_model) self.assertFalse(view.model()) # should work view.setModel(self.model) self.assertEqual(view.model(), self.model) def testSetCurrentLayer(self): view = QgsLayerTreeView() view.setModel(self.model) current_layer_changed_spy = QSignalSpy(view.currentLayerChanged) self.assertFalse(view.currentLayer()) view.setCurrentLayer(self.layer3) self.assertEqual(view.currentLayer(), self.layer3) self.assertEqual(len(current_layer_changed_spy), 1) view.setCurrentLayer(self.layer) self.assertEqual(view.currentLayer(), self.layer) self.assertEqual(len(current_layer_changed_spy), 2) view.setCurrentLayer(None) self.assertFalse(view.currentLayer()) self.assertEqual(len(current_layer_changed_spy), 3) def testDefaultActions(self): view = QgsLayerTreeView() view.setModel(self.model) actions = QgsLayerTreeViewDefaultActions(view) # show in overview action view.setCurrentLayer(self.layer) self.assertEqual(view.currentNode().customProperty('overview', 0), False) show_in_overview = actions.actionShowInOverview() show_in_overview.trigger() self.assertEqual(view.currentNode().customProperty('overview', 0), True) show_in_overview.trigger() self.assertEqual(view.currentNode().customProperty('overview', 0), False) def testMoveOutOfGroupActionLayer(self): """Test move out of group action on layer""" view = QgsLayerTreeView() group = self.project.layerTreeRoot().addGroup("embeddedgroup") group.addLayer(self.layer4) group.addLayer(self.layer5) groupname = group.name() view.setModel(self.model) actions = QgsLayerTreeViewDefaultActions(view) self.assertEqual( self.nodeOrder(self.project.layerTreeRoot().children()), [ self.layer.name(), self.layer2.name(), self.layer3.name(), groupname, groupname + '-' + self.layer4.name(), groupname + '-' + self.layer5.name(), ]) view.setCurrentLayer(self.layer5) moveOutOfGroup = actions.actionMoveOutOfGroup() moveOutOfGroup.trigger() self.assertEqual( self.nodeOrder(self.project.layerTreeRoot().children()), [ self.layer.name(), self.layer2.name(), self.layer3.name(), self.layer5.name(), groupname, groupname + '-' + self.layer4.name(), ]) def testMoveToTopActionLayer(self): """Test move to top action on layer""" view = QgsLayerTreeView() view.setModel(self.model) actions = QgsLayerTreeViewDefaultActions(view) self.assertEqual(self.project.layerTreeRoot().layerOrder(), [self.layer, self.layer2, self.layer3]) view.setCurrentLayer(self.layer3) movetotop = actions.actionMoveToTop() movetotop.trigger() self.assertEqual(self.project.layerTreeRoot().layerOrder(), [self.layer3, self.layer, self.layer2]) def testMoveToTopActionGroup(self): """Test move to top action on group""" view = QgsLayerTreeView() group = self.project.layerTreeRoot().addGroup("embeddedgroup") group.addLayer(self.layer4) group.addLayer(self.layer5) groupname = group.name() view.setModel(self.model) actions = QgsLayerTreeViewDefaultActions(view) self.assertEqual( self.nodeOrder(self.project.layerTreeRoot().children()), [ self.layer.name(), self.layer2.name(), self.layer3.name(), groupname, groupname + '-' + self.layer4.name(), groupname + '-' + self.layer5.name(), ]) nodeLayerIndex = self.model.node2index(group) view.setCurrentIndex(nodeLayerIndex) movetotop = actions.actionMoveToTop() movetotop.trigger() self.assertEqual( self.nodeOrder(self.project.layerTreeRoot().children()), [ groupname, groupname + '-' + self.layer4.name(), groupname + '-' + self.layer5.name(), self.layer.name(), self.layer2.name(), self.layer3.name(), ]) def testMoveToTopActionEmbeddedGroup(self): """Test move to top action on embeddedgroup layer""" view = QgsLayerTreeView() group = self.project.layerTreeRoot().addGroup("embeddedgroup") group.addLayer(self.layer4) group.addLayer(self.layer5) groupname = group.name() view.setModel(self.model) actions = QgsLayerTreeViewDefaultActions(view) self.assertEqual( self.nodeOrder(self.project.layerTreeRoot().children()), [ self.layer.name(), self.layer2.name(), self.layer3.name(), groupname, groupname + '-' + self.layer4.name(), groupname + '-' + self.layer5.name(), ]) view.setCurrentLayer(self.layer5) movetotop = actions.actionMoveToTop() movetotop.trigger() self.assertEqual( self.nodeOrder(self.project.layerTreeRoot().children()), [ self.layer.name(), self.layer2.name(), self.layer3.name(), groupname, groupname + '-' + self.layer5.name(), groupname + '-' + self.layer4.name(), ])
export_type = sys.argv[sys.argv.index("-T") + 1] if "-D" in sys.argv: target_dir = sys.argv[sys.argv.index("-D") + 1] if "-O" in sys.argv: output_log = sys.argv[sys.argv.index("-O") + 1] # Instantiate QGIS QgsApplication.setPrefixPath(qgisPrefixPath, True) qgs = QgsApplication([], True) QgsApplication.initQgis() # Open the project p = QgsProject() p.read(project_path) canvas = QgsMapCanvas() bridge = QgsLayerTreeMapCanvasBridge(p.layerTreeRoot(), canvas) bridge.setCanvasLayers() # Get the layers in the project layerList = p.mapLayersByName(parcelle_layer) if not layerList: layers = p.mapLayers() for lname, layer in layers.items(): print(lname + ' ' + layer.name() + ' ' + parcelle_layer) layerList = [ layer for lname, layer in layers.items() if layer.name() == parcelle_layer ] layer = layerList[0] # Get Feature
def testCustomLayerOrder(self): """ test project layer order""" prj = QgsProject() layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory") layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2", "memory") layer3 = QgsVectorLayer("Point?field=fldtxt:string", "layer3", "memory") prj.addMapLayers([layer, layer2, layer3]) layer_order_changed_spy = QSignalSpy(prj.layerTreeRoot().customLayerOrderChanged) prj.layerTreeRoot().setCustomLayerOrder([layer2, layer]) self.assertEqual(len(layer_order_changed_spy), 1) prj.layerTreeRoot().setCustomLayerOrder([layer2, layer]) self.assertEqual(len(layer_order_changed_spy), 1) # no signal, order not changed self.assertEqual(prj.layerTreeRoot().customLayerOrder(), [layer2, layer]) prj.layerTreeRoot().setCustomLayerOrder([layer]) self.assertEqual(prj.layerTreeRoot().customLayerOrder(), [layer]) self.assertEqual(len(layer_order_changed_spy), 2) # remove a layer prj.layerTreeRoot().setCustomLayerOrder([layer2, layer, layer3]) self.assertEqual(len(layer_order_changed_spy), 3) prj.removeMapLayer(layer) self.assertEqual(prj.layerTreeRoot().customLayerOrder(), [layer2, layer3]) self.assertEqual(len(layer_order_changed_spy), 4) # save and restore file_name = os.path.join(QDir.tempPath(), 'proj.qgs') prj.setFileName(file_name) prj.write() prj2 = QgsProject() prj2.setFileName(file_name) prj2.read() self.assertEqual([l.id() for l in prj2.layerTreeRoot().customLayerOrder()], [layer2.id(), layer3.id()]) # clear project prj.clear() self.assertEqual(prj.layerTreeRoot().customLayerOrder(), [])
class TestQgsLayerTreeView(unittest.TestCase): def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) # setup a dummy project self.project = QgsProject() self.layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory") self.layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2", "memory") self.layer3 = QgsVectorLayer("Point?field=fldtxt:string", "layer3", "memory") self.layer4 = QgsVectorLayer("Point?field=fldtxt:string", "layer4", "memory") self.layer5 = QgsVectorLayer("Point?field=fldtxt:string", "layer5", "memory") self.project.addMapLayers([self.layer, self.layer2, self.layer3]) self.model = QgsLayerTreeModel(self.project.layerTreeRoot()) def nodeOrder(self, group): nodeorder = [] layerTree = QgsLayerTree() for node in group: if QgsLayerTree.isGroup(node): groupname = node.name() nodeorder.append(groupname) for child in self.nodeOrder(node.children()): nodeorder.append(groupname + '-' + child) elif QgsLayerTree.isLayer(node): nodeorder.append(node.layer().name()) return nodeorder def testSetModel(self): view = QgsLayerTreeView() # should not work string_list_model = QStringListModel() view.setModel(string_list_model) self.assertFalse(view.model()) # should work view.setModel(self.model) self.assertEqual(view.model(), self.model) def testSetCurrentLayer(self): view = QgsLayerTreeView() view.setModel(self.model) current_layer_changed_spy = QSignalSpy(view.currentLayerChanged) self.assertFalse(view.currentLayer()) view.setCurrentLayer(self.layer3) self.assertEqual(view.currentLayer(), self.layer3) self.assertEqual(len(current_layer_changed_spy), 1) view.setCurrentLayer(self.layer) self.assertEqual(view.currentLayer(), self.layer) self.assertEqual(len(current_layer_changed_spy), 2) view.setCurrentLayer(None) self.assertFalse(view.currentLayer()) self.assertEqual(len(current_layer_changed_spy), 3) def testDefaultActions(self): view = QgsLayerTreeView() view.setModel(self.model) actions = QgsLayerTreeViewDefaultActions(view) # show in overview action view.setCurrentLayer(self.layer) self.assertEqual(view.currentNode().customProperty('overview', 0), False) show_in_overview = actions.actionShowInOverview() show_in_overview.trigger() self.assertEqual(view.currentNode().customProperty('overview', 0), True) show_in_overview.trigger() self.assertEqual(view.currentNode().customProperty('overview', 0), False) def testMoveOutOfGroupActionLayer(self): """Test move out of group action on layer""" view = QgsLayerTreeView() group = self.project.layerTreeRoot().addGroup("embeddedgroup") group.addLayer(self.layer4) group.addLayer(self.layer5) groupname = group.name() view.setModel(self.model) actions = QgsLayerTreeViewDefaultActions(view) self.assertEqual(self.nodeOrder(self.project.layerTreeRoot().children()), [ self.layer.name(), self.layer2.name(), self.layer3.name(), groupname, groupname + '-' + self.layer4.name(), groupname + '-' + self.layer5.name(), ]) view.setCurrentLayer(self.layer5) moveOutOfGroup = actions.actionMoveOutOfGroup() moveOutOfGroup.trigger() self.assertEqual(self.nodeOrder(self.project.layerTreeRoot().children()), [ self.layer.name(), self.layer2.name(), self.layer3.name(), self.layer5.name(), groupname, groupname + '-' + self.layer4.name(), ]) def testMoveToTopActionLayer(self): """Test move to top action on layer""" view = QgsLayerTreeView() view.setModel(self.model) actions = QgsLayerTreeViewDefaultActions(view) self.assertEqual(self.project.layerTreeRoot().layerOrder(), [self.layer, self.layer2, self.layer3]) view.setCurrentLayer(self.layer3) movetotop = actions.actionMoveToTop() movetotop.trigger() self.assertEqual(self.project.layerTreeRoot().layerOrder(), [self.layer3, self.layer, self.layer2]) def testMoveToTopActionGroup(self): """Test move to top action on group""" view = QgsLayerTreeView() group = self.project.layerTreeRoot().addGroup("embeddedgroup") group.addLayer(self.layer4) group.addLayer(self.layer5) groupname = group.name() view.setModel(self.model) actions = QgsLayerTreeViewDefaultActions(view) self.assertEqual(self.nodeOrder(self.project.layerTreeRoot().children()), [ self.layer.name(), self.layer2.name(), self.layer3.name(), groupname, groupname + '-' + self.layer4.name(), groupname + '-' + self.layer5.name(), ]) nodeLayerIndex = self.model.node2index(group) view.setCurrentIndex(nodeLayerIndex) movetotop = actions.actionMoveToTop() movetotop.trigger() self.assertEqual(self.nodeOrder(self.project.layerTreeRoot().children()), [ groupname, groupname + '-' + self.layer4.name(), groupname + '-' + self.layer5.name(), self.layer.name(), self.layer2.name(), self.layer3.name(), ]) def testMoveToTopActionEmbeddedGroup(self): """Test move to top action on embeddedgroup layer""" view = QgsLayerTreeView() group = self.project.layerTreeRoot().addGroup("embeddedgroup") group.addLayer(self.layer4) group.addLayer(self.layer5) groupname = group.name() view.setModel(self.model) actions = QgsLayerTreeViewDefaultActions(view) self.assertEqual(self.nodeOrder(self.project.layerTreeRoot().children()), [ self.layer.name(), self.layer2.name(), self.layer3.name(), groupname, groupname + '-' + self.layer4.name(), groupname + '-' + self.layer5.name(), ]) view.setCurrentLayer(self.layer5) movetotop = actions.actionMoveToTop() movetotop.trigger() self.assertEqual(self.nodeOrder(self.project.layerTreeRoot().children()), [ self.layer.name(), self.layer2.name(), self.layer3.name(), groupname, groupname + '-' + self.layer5.name(), groupname + '-' + self.layer4.name(), ])
def print_atlas(project_path, composer_name, predefined_scales, feature_filter, page_name_expression=None): if not feature_filter: QgsMessageLog.logMessage("atlasprint: NO feature_filter provided !", 'atlasprint', Qgis.Critical) return None # Get composer from project # in QGIS 2, we can't get composers without iface # so we reading project xml and extract composer # TODO Since QGIS 3.0, we should be able to use project layoutManager() # noinspection PyPep8Naming from xml.etree import ElementTree as ET composer_xml = None with open(project_path, 'r') as f: tree = ET.parse(f) for elem in tree.findall('.//Composer[@title="%s"]' % composer_name): composer_xml = ET.tostring( elem, encoding='utf8', method='xml' ) if not composer_xml: for elem in tree.findall('.//Layout[@name="%s"]' % composer_name): composer_xml = ET.tostring( elem, encoding='utf8', method='xml' ) if not composer_xml: QgsMessageLog.logMessage("atlasprint: Composer XML not parsed !", 'atlasprint', Qgis.Critical) return None document = QDomDocument() document.setContent(composer_xml) # Get canvas, map setting & instantiate composition canvas = QgsMapCanvas() project = QgsProject() project.read(project_path) bridge = QgsLayerTreeMapCanvasBridge( project.layerTreeRoot(), canvas ) bridge.setCanvasLayers() layout = QgsPrintLayout(project) # Load content from XML layout.loadFromTemplate( document, QgsReadWriteContext(), ) atlas = layout.atlas() atlas.setEnabled(True) atlas_map = layout.referenceMap() atlas_map.setAtlasDriven(True) atlas_map.setAtlasScalingMode(QgsLayoutItemMap.Predefined) layout.reportContext().setPredefinedScales(predefined_scales) if page_name_expression: atlas.setPageNameExpression(page_name_expression) # Filter feature here to avoid QGIS looping through every feature when doing : composition.setAtlasMode(QgsComposition.ExportAtlas) coverage_layer = atlas.coverageLayer() # Filter by FID as QGIS cannot compile expressions with $id or other $ vars # which leads to bad performance for big dataset use_fid = None if '$id' in feature_filter: import re ids = list(map(int, re.findall(r'\d+', feature_filter))) if len(ids) > 0: use_fid = ids[0] if use_fid: qReq = QgsFeatureRequest().setFilterFid(use_fid) else: qReq = QgsFeatureRequest().setFilterExpression(feature_filter) # Change feature_filter in order to improve performance pks = coverage_layer.dataProvider().pkAttributeIndexes() if use_fid and len(pks) == 1: pk = coverage_layer.dataProvider().fields()[pks[0]].name() feature_filter = '"%s" IN (%s)' % (pk, use_fid) QgsMessageLog.logMessage("atlasprint: feature_filter changed into: %s" % feature_filter, 'atlasprint', Qgis.Info) qReq = QgsFeatureRequest().setFilterExpression(feature_filter) atlas.setFilterFeatures(True) atlas.setFilterExpression(feature_filter) uid = uuid4() i = 0 # We use a single page for now. atlas.beginRender() atlas.seekTo(i) # setup settings settings = QgsLayoutExporter.PdfExportSettings() export_path = os.path.join( tempfile.gettempdir(), '%s_%s.pdf' % (atlas.nameForPage(i), uid) ) exporter = QgsLayoutExporter(layout) result = exporter.exportToPdf(export_path, settings) atlas.endRender() if result != QgsLayoutExporter.Success: QgsMessageLog.logMessage("atlasprint: export not generated %s" % export_path, 'atlasprint', Qgis.Critical) return None if not os.path.isfile(export_path): QgsMessageLog.logMessage("atlasprint: export not generated %s" % export_path, 'atlasprint', Qgis.Critical) return None QgsMessageLog.logMessage("atlasprint: path generated %s" % export_path, 'atlasprint', Qgis.Success) return export_path
def test_nested_groups(self): """ Test logic relating to nested groups with group layers """ p = QgsProject() layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory") p.addMapLayer(layer, False) layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2", "memory") p.addMapLayer(layer2, False) layer3 = QgsVectorLayer("Point?field=fldtxt:string", "layer3", "memory") p.addMapLayer(layer3, False) layer4 = QgsVectorLayer("Point?field=fldtxt:string", "layer4", "memory") p.addMapLayer(layer4, False) group_node = p.layerTreeRoot().addGroup('my group') group_node.addLayer(layer) group_node.addLayer(layer2) child_group = group_node.addGroup('child') layer3_node = child_group.addLayer(layer3) grandchild_group = child_group.addGroup('grandchild') layer4_node = grandchild_group.addLayer(layer4) self.assertEqual(p.layerTreeRoot().layerOrder(), [layer, layer2, layer3, layer4]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [layer, layer2, layer3, layer4]) spy = QSignalSpy(p.layerTreeRoot().layerOrderChanged) options = QgsGroupLayer.LayerOptions(QgsCoordinateTransformContext()) group_layer = group_node.convertToGroupLayer(options) p.addMapLayer(group_layer, False) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [layer4, layer3, layer2, layer]) spy_count = len(spy) self.assertEqual(spy_count, 1) grandchild_group_layer = grandchild_group.convertToGroupLayer(options) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [grandchild_group_layer, layer3, layer2, layer]) self.assertEqual(grandchild_group_layer.childLayers(), [layer4]) self.assertGreater(len(spy), spy_count) spy_count = len(spy) layer4_node.setItemVisibilityChecked(False) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [grandchild_group_layer, layer3, layer2, layer]) self.assertEqual(grandchild_group_layer.childLayers(), []) self.assertGreater(len(spy), spy_count) spy_count = len(spy) layer4_node.setItemVisibilityChecked(True) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [grandchild_group_layer, layer3, layer2, layer]) self.assertEqual(grandchild_group_layer.childLayers(), [layer4]) self.assertGreater(len(spy), spy_count) spy_count = len(spy) grandchild_group.setItemVisibilityChecked(False) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [layer3, layer2, layer]) self.assertGreater(len(spy), spy_count) spy_count = len(spy) grandchild_group.setItemVisibilityChecked(True) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [grandchild_group_layer, layer3, layer2, layer]) self.assertEqual(grandchild_group_layer.childLayers(), [layer4]) self.assertGreater(len(spy), spy_count) spy_count = len(spy) child_group_layer = child_group.convertToGroupLayer(options) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [child_group_layer, layer2, layer]) self.assertEqual(child_group_layer.childLayers(), [grandchild_group_layer, layer3]) self.assertEqual(grandchild_group_layer.childLayers(), [layer4]) self.assertGreater(len(spy), spy_count) spy_count = len(spy) layer4_node.setItemVisibilityChecked(False) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [child_group_layer, layer2, layer]) self.assertEqual(child_group_layer.childLayers(), [grandchild_group_layer, layer3]) self.assertEqual(grandchild_group_layer.childLayers(), []) self.assertGreater(len(spy), spy_count) spy_count = len(spy) layer4_node.setItemVisibilityChecked(True) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [child_group_layer, layer2, layer]) self.assertEqual(child_group_layer.childLayers(), [grandchild_group_layer, layer3]) self.assertEqual(grandchild_group_layer.childLayers(), [layer4]) self.assertGreater(len(spy), spy_count) spy_count = len(spy) grandchild_group.setItemVisibilityChecked(False) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [child_group_layer, layer2, layer]) self.assertEqual(child_group_layer.childLayers(), [layer3]) self.assertGreater(len(spy), spy_count) spy_count = len(spy) grandchild_group.setItemVisibilityChecked(True) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [child_group_layer, layer2, layer]) self.assertEqual(child_group_layer.childLayers(), [grandchild_group_layer, layer3]) self.assertEqual(grandchild_group_layer.childLayers(), [layer4]) self.assertGreater(len(spy), spy_count) spy_count = len(spy) layer3_node.setItemVisibilityChecked(False) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [child_group_layer, layer2, layer]) self.assertEqual(child_group_layer.childLayers(), [grandchild_group_layer]) self.assertEqual(grandchild_group_layer.childLayers(), [layer4]) self.assertGreater(len(spy), spy_count) spy_count = len(spy) layer3_node.setItemVisibilityChecked(True) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [child_group_layer, layer2, layer]) self.assertEqual(child_group_layer.childLayers(), [grandchild_group_layer, layer3]) self.assertEqual(grandchild_group_layer.childLayers(), [layer4]) self.assertGreater(len(spy), spy_count) spy_count = len(spy) grandchild_group.setGroupLayer(None) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [child_group_layer, layer2, layer]) self.assertEqual(child_group_layer.childLayers(), [layer4, layer3]) self.assertGreater(len(spy), spy_count) spy_count = len(spy) child_group.setGroupLayer(None) self.assertEqual(p.layerTreeRoot().layerOrder(), [group_layer]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [group_layer]) self.assertEqual(group_layer.childLayers(), [layer4, layer3, layer2, layer]) self.assertGreater(len(spy), spy_count) spy_count = len(spy) group_node.setGroupLayer(None) self.assertEqual(p.layerTreeRoot().layerOrder(), [layer, layer2, layer3, layer4]) self.assertEqual(p.layerTreeRoot().checkedLayers(), [layer, layer2, layer3, layer4]) self.assertGreater(len(spy), spy_count)
class TestQgsLayerTreeView(unittest.TestCase): def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) # setup a dummy project self.project = QgsProject() self.layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory") self.layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2", "memory") self.layer3 = QgsVectorLayer("Point?field=fldtxt:string", "layer3", "memory") self.layer4 = QgsVectorLayer("Point?field=fldtxt:string", "layer4", "memory") self.layer5 = QgsVectorLayer("Point?field=fldtxt:string", "layer5", "memory") self.project.addMapLayers([self.layer, self.layer2, self.layer3]) self.model = QgsLayerTreeModel(self.project.layerTreeRoot()) if USE_MODEL_TESTER: self.tester = QAbstractItemModelTester(self.model) def nodeOrder(self, group): nodeorder = [] for node in group: if QgsLayerTree.isGroup(node): groupname = node.name() nodeorder.append(groupname) for child in self.nodeOrder(node.children()): nodeorder.append(groupname + '-' + child) elif QgsLayerTree.isLayer(node): nodeorder.append(node.layer().name()) return nodeorder def testSetModel(self): view = QgsLayerTreeView() # should not work string_list_model = QStringListModel() view.setModel(string_list_model) self.assertFalse(view.model()) # should work view.setModel(self.model) if USE_MODEL_TESTER: proxy_tester = QAbstractItemModelTester(view.model()) self.assertEqual(view.layerTreeModel(), self.model) def testSetCurrentLayer(self): view = QgsLayerTreeView() view.setModel(self.model) if USE_MODEL_TESTER: proxy_tester = QAbstractItemModelTester(view.model()) current_layer_changed_spy = QSignalSpy(view.currentLayerChanged) self.assertFalse(view.currentLayer()) view.setCurrentLayer(self.layer3) self.assertEqual(view.currentLayer(), self.layer3) self.assertEqual(len(current_layer_changed_spy), 1) view.setCurrentLayer(self.layer) self.assertEqual(view.currentLayer(), self.layer) self.assertEqual(len(current_layer_changed_spy), 2) view.setCurrentLayer(None) self.assertFalse(view.currentLayer()) self.assertEqual(len(current_layer_changed_spy), 3) def testDefaultActions(self): view = QgsLayerTreeView() view.setModel(self.model) if USE_MODEL_TESTER: proxy_tester = QAbstractItemModelTester(view.model()) actions = QgsLayerTreeViewDefaultActions(view) # show in overview action view.setCurrentLayer(self.layer) self.assertEqual(view.currentNode().customProperty('overview', 0), False) show_in_overview = actions.actionShowInOverview() show_in_overview.trigger() self.assertEqual(view.currentNode().customProperty('overview', 0), True) show_in_overview.trigger() self.assertEqual(view.currentNode().customProperty('overview', 0), False) def testMoveOutOfGroupActionLayer(self): """Test move out of group action on layer""" view = QgsLayerTreeView() group = self.project.layerTreeRoot().addGroup("embeddedgroup") group.addLayer(self.layer4) group.addLayer(self.layer5) groupname = group.name() view.setModel(self.model) if USE_MODEL_TESTER: proxy_tester = QAbstractItemModelTester(view.model()) actions = QgsLayerTreeViewDefaultActions(view) self.assertEqual( self.nodeOrder(self.project.layerTreeRoot().children()), [ self.layer.name(), self.layer2.name(), self.layer3.name(), groupname, groupname + '-' + self.layer4.name(), groupname + '-' + self.layer5.name(), ]) view.setCurrentLayer(self.layer5) moveOutOfGroup = actions.actionMoveOutOfGroup() moveOutOfGroup.trigger() self.assertEqual( self.nodeOrder(self.project.layerTreeRoot().children()), [ self.layer.name(), self.layer2.name(), self.layer3.name(), self.layer5.name(), groupname, groupname + '-' + self.layer4.name(), ]) def testMoveToTopActionLayer(self): """Test move to top action on layer""" view = QgsLayerTreeView() view.setModel(self.model) if USE_MODEL_TESTER: proxy_tester = QAbstractItemModelTester(view.model()) actions = QgsLayerTreeViewDefaultActions(view) self.assertEqual(self.project.layerTreeRoot().layerOrder(), [self.layer, self.layer2, self.layer3]) view.setCurrentLayer(self.layer3) movetotop = actions.actionMoveToTop() movetotop.trigger() self.assertEqual(self.project.layerTreeRoot().layerOrder(), [self.layer3, self.layer, self.layer2]) def testMoveToTopActionGroup(self): """Test move to top action on group""" view = QgsLayerTreeView() group = self.project.layerTreeRoot().addGroup("embeddedgroup") group.addLayer(self.layer4) group.addLayer(self.layer5) groupname = group.name() view.setModel(self.model) if USE_MODEL_TESTER: proxy_tester = QAbstractItemModelTester(view.model()) actions = QgsLayerTreeViewDefaultActions(view) self.assertEqual( self.nodeOrder(self.project.layerTreeRoot().children()), [ self.layer.name(), self.layer2.name(), self.layer3.name(), groupname, groupname + '-' + self.layer4.name(), groupname + '-' + self.layer5.name(), ]) nodeLayerIndex = view.node2index(group) view.setCurrentIndex(nodeLayerIndex) movetotop = actions.actionMoveToTop() movetotop.trigger() self.assertEqual( self.nodeOrder(self.project.layerTreeRoot().children()), [ groupname, groupname + '-' + self.layer4.name(), groupname + '-' + self.layer5.name(), self.layer.name(), self.layer2.name(), self.layer3.name(), ]) def testMoveToTopActionEmbeddedGroup(self): """Test move to top action on embeddedgroup layer""" view = QgsLayerTreeView() group = self.project.layerTreeRoot().addGroup("embeddedgroup") group.addLayer(self.layer4) group.addLayer(self.layer5) groupname = group.name() view.setModel(self.model) if USE_MODEL_TESTER: proxy_tester = QAbstractItemModelTester(view.model()) actions = QgsLayerTreeViewDefaultActions(view) self.assertEqual( self.nodeOrder(self.project.layerTreeRoot().children()), [ self.layer.name(), self.layer2.name(), self.layer3.name(), groupname, groupname + '-' + self.layer4.name(), groupname + '-' + self.layer5.name(), ]) view.setCurrentLayer(self.layer5) movetotop = actions.actionMoveToTop() movetotop.trigger() self.assertEqual( self.nodeOrder(self.project.layerTreeRoot().children()), [ self.layer.name(), self.layer2.name(), self.layer3.name(), groupname, groupname + '-' + self.layer5.name(), groupname + '-' + self.layer4.name(), ]) def testMoveToTopActionLayerAndGroup(self): """Test move to top action for a group and it's layer simultaneously""" view = QgsLayerTreeView() group = self.project.layerTreeRoot().addGroup("embeddedgroup") group.addLayer(self.layer4) group.addLayer(self.layer5) groupname = group.name() view.setModel(self.model) if USE_MODEL_TESTER: proxy_tester = QAbstractItemModelTester(view.model()) actions = QgsLayerTreeViewDefaultActions(view) self.assertEqual( self.nodeOrder(self.project.layerTreeRoot().children()), [ self.layer.name(), self.layer2.name(), self.layer3.name(), groupname, groupname + '-' + self.layer4.name(), groupname + '-' + self.layer5.name(), ]) selectionMode = view.selectionMode() view.setSelectionMode(QgsLayerTreeView.MultiSelection) nodeLayerIndex = view.node2index(group) view.setCurrentIndex(nodeLayerIndex) view.setCurrentLayer(self.layer5) view.setSelectionMode(selectionMode) movetotop = actions.actionMoveToTop() movetotop.trigger() self.assertEqual( self.nodeOrder(self.project.layerTreeRoot().children()), [ groupname, groupname + '-' + self.layer5.name(), groupname + '-' + self.layer4.name(), self.layer.name(), self.layer2.name(), self.layer3.name(), ]) def testMoveToBottomActionLayer(self): """Test move to bottom action on layer""" view = QgsLayerTreeView() view.setModel(self.model) if USE_MODEL_TESTER: proxy_tester = QAbstractItemModelTester(view.model()) actions = QgsLayerTreeViewDefaultActions(view) self.assertEqual(self.project.layerTreeRoot().layerOrder(), [self.layer, self.layer2, self.layer3]) view.setCurrentLayer(self.layer) movetobottom = actions.actionMoveToBottom() movetobottom.trigger() self.assertEqual(self.project.layerTreeRoot().layerOrder(), [self.layer2, self.layer3, self.layer]) def testMoveToBottomActionGroup(self): """Test move to bottom action on group""" view = QgsLayerTreeView() group = self.project.layerTreeRoot().insertGroup(0, "embeddedgroup") group.addLayer(self.layer4) group.addLayer(self.layer5) groupname = group.name() view.setModel(self.model) if USE_MODEL_TESTER: proxy_tester = QAbstractItemModelTester(view.model()) actions = QgsLayerTreeViewDefaultActions(view) self.assertEqual( self.nodeOrder(self.project.layerTreeRoot().children()), [ groupname, groupname + '-' + self.layer4.name(), groupname + '-' + self.layer5.name(), self.layer.name(), self.layer2.name(), self.layer3.name(), ]) nodeLayerIndex = view.node2index(group) view.setCurrentIndex(nodeLayerIndex) movetobottom = actions.actionMoveToBottom() movetobottom.trigger() self.assertEqual( self.nodeOrder(self.project.layerTreeRoot().children()), [ self.layer.name(), self.layer2.name(), self.layer3.name(), groupname, groupname + '-' + self.layer4.name(), groupname + '-' + self.layer5.name(), ]) def testMoveToBottomActionEmbeddedGroup(self): """Test move to bottom action on embeddedgroup layer""" view = QgsLayerTreeView() group = self.project.layerTreeRoot().addGroup("embeddedgroup") group.addLayer(self.layer4) group.addLayer(self.layer5) groupname = group.name() view.setModel(self.model) if USE_MODEL_TESTER: proxy_tester = QAbstractItemModelTester(view.model()) actions = QgsLayerTreeViewDefaultActions(view) self.assertEqual( self.nodeOrder(self.project.layerTreeRoot().children()), [ self.layer.name(), self.layer2.name(), self.layer3.name(), groupname, groupname + '-' + self.layer4.name(), groupname + '-' + self.layer5.name(), ]) view.setCurrentLayer(self.layer4) movetobottom = actions.actionMoveToBottom() movetobottom.trigger() self.assertEqual( self.nodeOrder(self.project.layerTreeRoot().children()), [ self.layer.name(), self.layer2.name(), self.layer3.name(), groupname, groupname + '-' + self.layer5.name(), groupname + '-' + self.layer4.name(), ]) def testMoveToBottomActionLayerAndGroup(self): """Test move to top action for a group and it's layer simultaneously""" view = QgsLayerTreeView() group = self.project.layerTreeRoot().insertGroup(0, "embeddedgroup") group.addLayer(self.layer4) group.addLayer(self.layer5) groupname = group.name() view.setModel(self.model) if USE_MODEL_TESTER: proxy_tester = QAbstractItemModelTester(view.model()) actions = QgsLayerTreeViewDefaultActions(view) self.assertEqual( self.nodeOrder(self.project.layerTreeRoot().children()), [ groupname, groupname + '-' + self.layer4.name(), groupname + '-' + self.layer5.name(), self.layer.name(), self.layer2.name(), self.layer3.name(), ]) selectionMode = view.selectionMode() view.setSelectionMode(QgsLayerTreeView.MultiSelection) nodeLayerIndex = view.node2index(group) view.setCurrentIndex(nodeLayerIndex) view.setCurrentLayer(self.layer4) view.setSelectionMode(selectionMode) movetobottom = actions.actionMoveToBottom() movetobottom.trigger() self.assertEqual( self.nodeOrder(self.project.layerTreeRoot().children()), [ self.layer.name(), self.layer2.name(), self.layer3.name(), groupname, groupname + '-' + self.layer5.name(), groupname + '-' + self.layer4.name(), ]) def testSetLayerVisible(self): view = QgsLayerTreeView() view.setModel(self.model) if USE_MODEL_TESTER: proxy_tester = QAbstractItemModelTester(view.model()) self.project.layerTreeRoot().findLayer( self.layer).setItemVisibilityChecked(True) self.project.layerTreeRoot().findLayer( self.layer2).setItemVisibilityChecked(True) self.assertTrue(self.project.layerTreeRoot().findLayer( self.layer).itemVisibilityChecked()) self.assertTrue(self.project.layerTreeRoot().findLayer( self.layer2).itemVisibilityChecked()) view.setLayerVisible(None, True) view.setLayerVisible(self.layer, True) self.assertTrue(self.project.layerTreeRoot().findLayer( self.layer).itemVisibilityChecked()) view.setLayerVisible(self.layer2, False) self.assertFalse(self.project.layerTreeRoot().findLayer( self.layer2).itemVisibilityChecked()) view.setLayerVisible(self.layer2, True) self.assertTrue(self.project.layerTreeRoot().findLayer( self.layer2).itemVisibilityChecked()) def testProxyModel(self): """Test proxy model filtering and private layers""" view = QgsLayerTreeView() view.setModel(self.model) if USE_MODEL_TESTER: proxy_tester = QAbstractItemModelTester(view.model()) tree_model = view.layerTreeModel() proxy_model = view.proxyModel() self.assertEqual(tree_model.rowCount(), 3) self.assertEqual(proxy_model.rowCount(), 3) items = [] for r in range(tree_model.rowCount()): items.append(tree_model.data(tree_model.index(r, 0))) self.assertEqual(items, ['layer1', 'layer2', 'layer3']) proxy_items = [] for r in range(proxy_model.rowCount()): proxy_items.append(proxy_model.data(proxy_model.index(r, 0))) self.assertEqual(proxy_items, ['layer1', 'layer2', 'layer3']) self.layer3.setFlags(self.layer.Private) self.assertEqual(tree_model.rowCount(), 3) self.assertEqual(proxy_model.rowCount(), 2) proxy_items = [] for r in range(proxy_model.rowCount()): proxy_items.append(proxy_model.data(proxy_model.index(r, 0))) self.assertEqual(proxy_items, ['layer1', 'layer2']) view.setShowPrivateLayers(True) self.assertEqual(proxy_model.rowCount(), 3) proxy_items = [] for r in range(proxy_model.rowCount()): proxy_items.append(proxy_model.data(proxy_model.index(r, 0))) self.assertEqual(proxy_items, ['layer1', 'layer2', 'layer3']) view.setShowPrivateLayers(False) self.assertEqual(proxy_model.rowCount(), 2) proxy_items = [] for r in range(proxy_model.rowCount()): proxy_items.append(proxy_model.data(proxy_model.index(r, 0))) self.assertEqual(proxy_items, ['layer1', 'layer2']) # Test filters proxy_model.setFilterText('layer2') self.assertEqual(proxy_model.rowCount(), 1) proxy_items = [] for r in range(proxy_model.rowCount()): proxy_items.append(proxy_model.data(proxy_model.index(r, 0))) self.assertEqual(proxy_items, ['layer2']) def testProxyModelCurrentIndex(self): """Test a crash spotted out while developing the proxy model""" view = QgsLayerTreeView() view.setModel(self.model) if USE_MODEL_TESTER: proxy_tester = QAbstractItemModelTester(view.model()) tree_tester = QAbstractItemModelTester(view.layerTreeModel()) view.setCurrentLayer(self.layer3) self.layer3.setFlags(self.layer.Private) def testNode2IndexMethods(self): """Test node2index and node2sourceIndex""" view = QgsLayerTreeView() view.setModel(self.model) if USE_MODEL_TESTER: proxy_tester = QAbstractItemModelTester(view.model()) tree_tester = QAbstractItemModelTester(view.layerTreeModel()) tree_model = view.layerTreeModel() proxy_model = view.proxyModel() proxy_index = proxy_model.index(1, 0) node2 = view.index2node(proxy_index) self.assertEqual(node2.name(), 'layer2') proxy_layer2_index = view.node2index(node2) self.assertEqual(proxy_layer2_index, view.node2index(node2)) source_index = tree_model.index(1, 0) tree_layer2_index = view.node2sourceIndex(node2) self.assertEqual(tree_layer2_index, view.node2sourceIndex(node2))
if "-D" in sys.argv: target_dir = sys.argv[sys.argv.index("-D") + 1] if "-O" in sys.argv: output_log = sys.argv[sys.argv.index("-O") + 1] # Instantiate QGIS QgsApplication.setPrefixPath(qgisPrefixPath, True) qgs = QgsApplication([], True) QgsApplication.initQgis() # Open the project p = QgsProject() p.read(project_path) canvas = QgsMapCanvas() bridge = QgsLayerTreeMapCanvasBridge( p.layerTreeRoot(), canvas ) bridge.setCanvasLayers() # Get the layers in the project layerList = p.mapLayersByName(parcelle_layer) if not layerList: layers = p.mapLayers() for lname, layer in layers.items(): print(lname + ' ' + layer.name() + ' ' + parcelle_layer) layerList = [layer for lname, layer in layers.items() if layer.name() == parcelle_layer] layer = layerList[0] # Get Feature req = QgsFeatureRequest()
def setUpTestData(cls): super().setUpTestData() cls.temp_dir = QTemporaryDir() cls.temp_project_path = os.path.join(cls.temp_dir.path(), 'pg_openrouteservice.qgs') # Create test layer conn_str = "dbname='{NAME}' host={HOST} port={PORT} user='******' password='******' sslmode=disable".format( **settings.DATABASES['default']) cls.conn_uri = conn_str md = QgsProviderRegistry.instance().providerMetadata('postgres') conn = md.createConnection(conn_str, {}) conn.executeSql( "DROP SCHEMA IF EXISTS \"openrouteservice test\" CASCADE") conn.executeSql("CREATE SCHEMA \"openrouteservice test\"") conn.executeSql( "CREATE TABLE \"openrouteservice test\".openrouteservice_poly_not_compatible ( pk SERIAL NOT NULL, name TEXT, geom GEOMETRY(POLYGON, 4326), PRIMARY KEY ( pk ) )" ) conn.executeSql( "CREATE TABLE \"openrouteservice test\".openrouteservice_point_not_compatible ( pk SERIAL NOT NULL, value NUMERIC, group_index INTEGER, area NUMERIC, reachfactor NUMERIC, total_pop INTEGER, geom GEOMETRY(POINT, 4326), PRIMARY KEY ( pk ) )" ) conn.executeSql( "CREATE TABLE \"openrouteservice test\".openrouteservice_compatible ( pk SERIAL NOT NULL, value NUMERIC, group_index INTEGER, area NUMERIC, reachfactor NUMERIC, total_pop INTEGER, geom GEOMETRY(POLYGON, 4326), PRIMARY KEY ( pk ) )" ) conn.executeSql( "CREATE TABLE \"openrouteservice test\".openrouteservice_compatible_3857 ( pk SERIAL NOT NULL, value NUMERIC, group_index INTEGER, area NUMERIC, reachfactor NUMERIC, total_pop INTEGER, geom GEOMETRY(POLYGON, 3857), PRIMARY KEY ( pk ) )" ) # Input layers for async tests conn.executeSql( "CREATE TABLE \"openrouteservice test\".openrouteservice_point_3857 ( pk SERIAL NOT NULL, geom GEOMETRY(POINT, 3857), PRIMARY KEY ( pk ) )" ) conn.executeSql( "CREATE TABLE \"openrouteservice test\".openrouteservice_multipoint_4326 ( pk SERIAL NOT NULL, geom GEOMETRY(MULTIPOINT, 4326), PRIMARY KEY ( pk ) )" ) # Add sample points for async tests conn.executeSql( """INSERT INTO "openrouteservice test".openrouteservice_multipoint_4326 (geom) VALUES ( 'SRID=4326;MULTIPOINT ((-77.55542807059459 37.56350130888833), (-77.5513628235481 37.547924590224554), (-77.53848954123421 37.58068563329007), (-77.59608054105951 37.59518182260462))'::geometry), ('SRID=4326;MULTIPOINT ((-77.4077240945721 37.538254644499624), (-77.41991983571157 37.54470141434406), (-77.4260177062813 37.55920460826607), (-77.39349572990939 37.562427156963516), (-77.40840163574651 37.58337032579007))'::geometry)""" ) conn.executeSql( """INSERT INTO "openrouteservice test".openrouteservice_point_3857 (geom) VALUES ('SRID=3857;POINT (-8636824.820306677 4510025.909782101)'::geometry), ('SRID=3857;POINT (-8633657.031688528 4512364.0394764505)'::geometry), ('SRID=3857;POINT (-8637126.514460787 4512741.157169087)'::geometry), ('SRID=3857;POINT (-8634109.572919691 4503916.603161385)'::geometry)""" ) cls.layer_specs = {} project = QgsProject() for table_name, table_spec in { 'openrouteservice_poly_not_compatible': ('Polygon', 4326), 'openrouteservice_point_not_compatible': ('Point', 4326), 'openrouteservice_compatible': ('Polygon', 4326), 'openrouteservice_compatible_3857': ('Polygon', 3857), 'openrouteservice_point_3857': ('Point', 3857), 'openrouteservice_multipoint_4326': ('MultiPoint', 4326), }.items(): layer_uri = conn_str + " sslmode=disable key='pk' estimatedmetadata=false srid={srid} type={geometry_type} checkPrimaryKeyUnicity='0' table=\"openrouteservice test\".\"{table_name}\" (geom)".format( table_name=table_name, geometry_type=table_spec[0], srid=table_spec[1]) layer = QgsVectorLayer(layer_uri, table_name, 'postgres') assert layer.isValid() cls.layer_specs[table_name] = layer_uri project.addMapLayers([layer]) assert project.write(cls.temp_project_path) Project.objects.filter(title='Test openrouteservice project').delete() toc = buildLayerTreeNodeObject(project.layerTreeRoot()) cls.qdjango_project = Project(qgis_file=File( open(cls.temp_project_path, 'r')), title='Test openrouteservice project', group=cls.project_group, layers_tree=toc) cls.qdjango_project.save() for layer_id, layer in project.mapLayers().items(): _, created = Layer.objects.get_or_create( name=layer.name(), title=layer.name(), origname=layer.name(), qgs_layer_id=layer_id, srid=layer.crs().postgisSrid(), project=cls.qdjango_project, layer_type='postgres', datasource=cls.layer_specs[layer.name()]) assert created OpenrouteserviceProject.objects.get_or_create( project=cls.qdjango_project, services={OpenrouteserviceService.ISOCHRONE.value})
def create(self, path: str, qgis_project: QgsProject): qgis_project.setAutoTransaction(self.auto_transaction) qgis_project.setEvaluateDefaultValues(self.evaluate_default_values) qgis_layers = list() for layer in self.layers: qgis_layer = layer.create() self.layer_added.emit(qgis_layer.id()) if not self.crs and qgis_layer.isSpatial(): self.crs = qgis_layer.crs() qgis_layers.append(qgis_layer) qgis_project.addMapLayers(qgis_layers, not self.legend) if self.crs: if isinstance(self.crs, QgsCoordinateReferenceSystem): qgis_project.setCrs(self.crs) else: crs = QgsCoordinateReferenceSystem.fromEpsgId(self.crs) if not crs.isValid(): crs = QgsCoordinateReferenceSystem(self.crs) # Fallback qgis_project.setCrs(crs) qgis_relations = list( qgis_project.relationManager().relations().values()) dict_layers = {layer.layer.id(): layer for layer in self.layers} for relation in self.relations: rel = relation.create(qgis_project, qgis_relations) assert rel.isValid() qgis_relations.append(rel) referenced_layer = dict_layers.get(rel.referencedLayerId(), None) referencing_layer = dict_layers.get(rel.referencingLayerId(), None) if referenced_layer and referenced_layer.is_domain: editor_widget_setup = QgsEditorWidgetSetup( "RelationReference", { "Relation": rel.id(), "ShowForm": False, "OrderByValue": True, "ShowOpenFormButton": False, "AllowNULL": True, "FilterExpression": "\"{}\" = '{}'".format(ENUM_THIS_CLASS_COLUMN, relation.child_domain_name) if relation.child_domain_name else "", "FilterFields": list(), }, ) elif referenced_layer and referenced_layer.is_basket_table: editor_widget_setup = QgsEditorWidgetSetup( "RelationReference", { "Relation": rel.id(), "ShowForm": False, "OrderByValue": True, "ShowOpenFormButton": False, "AllowNULL": True, "AllowAddFeatures": False, "FilterExpression": "\"topic\" = '{}' and attribute(get_feature('{}', 't_id', \"dataset\"), 'datasetname') != '{}'" .format( referencing_layer.model_topic_name, "T_ILI2DB_DATASET" if referenced_layer.provider == "ogr" else "t_ili2db_dataset", CATALOGUE_DATASETNAME, ) if referencing_layer.model_topic_name else "", "FilterFields": list(), }, ) else: editor_widget_setup = QgsEditorWidgetSetup( "RelationReference", { "Relation": rel.id(), "ShowForm": False, "OrderByValue": True, "ShowOpenFormButton": False, "AllowAddFeatures": True, "AllowNULL": True, }, ) referencing_layer = rel.referencingLayer() referencing_layer.setEditorWidgetSetup(rel.referencingFields()[0], editor_widget_setup) qgis_project.relationManager().setRelations(qgis_relations) # Set Bag of Enum widget for layer_name, bag_of_enum in self.bags_of_enum.items(): for attribute, bag_of_enum_info in bag_of_enum.items(): layer_obj = bag_of_enum_info[0] cardinality = bag_of_enum_info[1] domain_table = bag_of_enum_info[2] key_field = bag_of_enum_info[3] value_field = bag_of_enum_info[4] minimal_selection = cardinality.startswith("1") current_layer = layer_obj.create() field_widget = "ValueRelation" field_widget_config = { "AllowMulti": True, "UseCompleter": False, "Value": value_field, "OrderByValue": False, "AllowNull": True, "Layer": domain_table.create().id(), "FilterExpression": "", "Key": key_field, "NofColumns": 1, } field_idx = current_layer.fields().indexOf(attribute) setup = QgsEditorWidgetSetup(field_widget, field_widget_config) current_layer.setEditorWidgetSetup(field_idx, setup) if minimal_selection: constraint_expression = 'array_length("{}")>0'.format( attribute) current_layer.setConstraintExpression( field_idx, constraint_expression, self.tr("The minimal selection is 1"), ) for layer in self.layers: layer.create_form(self) if self.legend: self.legend.create(qgis_project) custom_layer_order = list() for custom_layer_name in self.custom_layer_order_structure: custom_layer = qgis_project.mapLayersByName(custom_layer_name) if custom_layer: custom_layer_order.append(custom_layer[0]) if custom_layer_order: root = qgis_project.layerTreeRoot() order = root.customLayerOrder() if root.hasCustomLayerOrder( ) else [] order.extend(custom_layer_order) root.setCustomLayerOrder(custom_layer_order) root.setHasCustomLayerOrder(True) if path: qgis_project.write(path)
def print_layout( project: QgsProject, layout_name: str, output_format: OutputFormat, feature_filter: str = None, scales: list = None, scale: int = None, **kwargs, ): """Generate a PDF for an atlas or a report. :param project: The QGIS project. :type project: QgsProject :param layout_name: Name of the layout of the atlas or report. :type layout_name: basestring :param feature_filter: QGIS Expression to use to select the feature. It can return many features, a multiple pages PDF will be returned. This is required to print atlas, not report :type feature_filter: basestring :param scale: A scale to force in the atlas context. Default to None. :type scale: int :param scales: A list of predefined list of scales to force in the atlas context. Default to None. :type scales: list :param output_format: The output format, default to PDF if not provided. :return: Path to the PDF. :rtype: basestring """ canvas = QgsMapCanvas() bridge = QgsLayerTreeMapCanvasBridge(project.layerTreeRoot(), canvas) bridge.setCanvasLayers() manager = project.layoutManager() master_layout = manager.layoutByName(layout_name) if output_format == OutputFormat.Svg: settings = QgsLayoutExporter.SvgExportSettings() elif output_format in (OutputFormat.Png, OutputFormat.Jpeg): settings = QgsLayoutExporter.ImageExportSettings() else: # PDF by default settings = QgsLayoutExporter.PdfExportSettings() atlas = None atlas_layout = None report_layout = None logger = Logger() if not master_layout: raise AtlasPrintException("Layout `{}` not found".format(layout_name)) if master_layout.layoutType() == QgsMasterLayoutInterface.PrintLayout: for _print_layout in manager.printLayouts(): if _print_layout.name() == layout_name: atlas_layout = _print_layout break atlas = atlas_layout.atlas() if not atlas.enabled(): raise AtlasPrintException("The layout is not enabled for an atlas") layer = atlas.coverageLayer() if feature_filter is None: raise AtlasPrintException( "EXP_FILTER is mandatory to print an atlas layout") feature_filter = optimize_expression(layer, feature_filter) expression = QgsExpression(feature_filter) if expression.hasParserError(): raise AtlasPrintException( "Expression is invalid, parser error: {}".format( expression.parserErrorString())) context = QgsExpressionContext() context.appendScope(QgsExpressionContextUtils.globalScope()) context.appendScope(QgsExpressionContextUtils.projectScope(project)) context.appendScope( QgsExpressionContextUtils.layoutScope(atlas_layout)) context.appendScope(QgsExpressionContextUtils.atlasScope(atlas)) context.appendScope(QgsExpressionContextUtils.layerScope(layer)) expression.prepare(context) if expression.hasEvalError(): raise AtlasPrintException( "Expression is invalid, eval error: {}".format( expression.evalErrorString())) atlas.setFilterFeatures(True) atlas.setFilterExpression(feature_filter) atlas.updateFeatures() if scale: atlas_layout.referenceMap().setAtlasScalingMode( QgsLayoutItemMap.Fixed) atlas_layout.referenceMap().setScale(scale) if scales: atlas_layout.referenceMap().setAtlasScalingMode( QgsLayoutItemMap.Predefined) settings.predefinedMapScales = scales if (not scales and atlas_layout.referenceMap().atlasScalingMode() == QgsLayoutItemMap.Predefined): use_project = project.useProjectScales() map_scales = project.mapScales() if not use_project or len(map_scales) == 0: logger.info( "Map scales not found in project, fetching predefined map scales in global config" ) map_scales = global_scales() settings.predefinedMapScales = map_scales elif master_layout.layoutType() == QgsMasterLayoutInterface.Report: report_layout = master_layout else: raise AtlasPrintException("The layout is not supported by the plugin") for key, value in kwargs.items(): found = False if atlas_layout: item = atlas_layout.itemById(key.lower()) if isinstance(item, QgsLayoutItemLabel): item.setText(value) found = True logger.info( 'Additional parameters "{key}" {found} in layout, value "{value}"'. format(key=key, found="found" if found else "not found", value=value)) file_name = "{}_{}.{}".format(clean_string(layout_name), uuid4(), output_format.name.lower()) export_path = Path(tempfile.gettempdir()).joinpath(file_name) Logger().info("Exporting the request in {} using {}".format( export_path, output_format.value)) if output_format in (OutputFormat.Png, OutputFormat.Jpeg): exporter = QgsLayoutExporter(atlas_layout or report_layout) result = exporter.exportToImage(str(export_path), settings) error = result_message(result) elif output_format in (OutputFormat.Svg, ): exporter = QgsLayoutExporter(atlas_layout or report_layout) result = exporter.exportToSvg(str(export_path), settings) error = result_message(result) else: # Default to PDF result, error = QgsLayoutExporter.exportToPdf(atlas or report_layout, str(export_path), settings) # Let's override error message _ = error error = result_message(result) if result != QgsLayoutExporter.Success: raise Exception("Export not generated in QGIS exporter {} : {}".format( export_path, error)) if not export_path.is_file(): logger.warning( "No error from QGIS Exporter, but the file does not exist.\n" "Message from QGIS exporter : {}\n" "File path : {}\n".format(error, export_path)) raise Exception( "Export OK from QGIS, but file not found on the file system : {}". format(export_path)) return export_path
def test_project_server_validator(self): """Test project server validator.""" project = QgsProject() layer = QgsVectorLayer('Point?field=fldtxt:string', 'layer_1', 'memory') project.addMapLayers([layer]) # Valid valid, results = QgsProjectServerValidator.validate(project) self.assertTrue(valid) self.assertFalse(results) layer_1 = QgsVectorLayer('Point?field=fldtxt:string', 'layer_1', 'memory') project.addMapLayers([layer_1]) # Not valid, same layer name valid, results = QgsProjectServerValidator.validate(project) self.assertFalse(valid) self.assertEqual(1, len(results)) self.assertEqual(QgsProjectServerValidator.DuplicatedNames, results[0].error) # Not valid, short name is invalid layer_1.setShortName('layer_1_invalid_#') valid, results = QgsProjectServerValidator.validate(project) self.assertFalse(valid) self.assertEqual(1, len(results)) self.assertEqual(QgsProjectServerValidator.LayerShortName, results[0].error) # Not valid, same short name as the first layer name layer_1.setShortName('layer_1') valid, results = QgsProjectServerValidator.validate(project) self.assertFalse(valid) self.assertEqual(1, len(results)) self.assertEqual(QgsProjectServerValidator.DuplicatedNames, results[0].error) # Valid layer_1.setShortName('layer_1_bis') valid, results = QgsProjectServerValidator.validate(project) self.assertTrue(valid) self.assertEqual(0, len(results)) # Not valid, a group with same name as the first layer group = project.layerTreeRoot().addGroup('layer_1') valid, results = QgsProjectServerValidator.validate(project) self.assertFalse(valid) self.assertEqual(1, len(results)) self.assertEqual(QgsProjectServerValidator.DuplicatedNames, results[0].error) # Valid group.setCustomProperty('wmsShortName', 'my_group1') valid, results = QgsProjectServerValidator.validate(project) self.assertTrue(valid) self.assertEqual(0, len(results)) # Not valid, the project title is invalid project.setTitle('@ layer 1') valid, results = QgsProjectServerValidator.validate(project) self.assertFalse(valid) self.assertEqual(1, len(results)) self.assertEqual(QgsProjectServerValidator.ProjectShortName, results[0].error) # Valid project title project.setTitle('project_title') valid, results = QgsProjectServerValidator.validate(project) self.assertTrue(valid) self.assertEqual(0, len(results)) # Valid despite the bad project title, use project short name project.setTitle('@ layer 1') project.writeEntry('WMSRootName', '/', 'project_short_name') valid, results = QgsProjectServerValidator.validate(project) self.assertTrue(valid) self.assertEqual(0, len(results)) # Not valid project short name project.setTitle('project_title') project.writeEntry('WMSRootName', '/', 'project with space') valid, results = QgsProjectServerValidator.validate(project) self.assertFalse(valid) self.assertEqual(1, len(results)) self.assertEqual(QgsProjectServerValidator.ProjectShortName, results[0].error) # Not valid, duplicated project short name project.writeEntry('WMSRootName', '/', 'layer_1') valid, results = QgsProjectServerValidator.validate(project) self.assertEqual(1, len(results)) self.assertEqual(QgsProjectServerValidator.ProjectRootNameConflict, results[0].error)
target_dir = sys.argv[sys.argv.index("-D") + 1] if("-O" in sys.argv): output_log = sys.argv[sys.argv.index("-O") + 1] # Instantiate QGIS QgsApplication.setPrefixPath(qgisPrefixPath, True) qgs = QgsApplication([], True) QgsApplication.initQgis() # Open the project p = QgsProject() p.read(project_path) canvas = QgsMapCanvas() bridge = QgsLayerTreeMapCanvasBridge( p.layerTreeRoot(), canvas ) bridge.setCanvasLayers() # Get the layers in the project layerList = p.mapLayersByName(parcelle_layer) if not layerList: layers = p.mapLayers() for lname,layer in layers.items(): print(lname+' '+layer.name()+' '+parcelle_layer) layerList = [ layer for lname,layer in layers.items() if layer.name() == parcelle_layer ] layer = layerList[0] # Get Feature req = QgsFeatureRequest()
self.layBotonera.addWidget(boto) self.fBotonera.show() spacer = QtWidgets.QSpacerItem(0, 0, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.layBotonera.addSpacerItem(spacer) # Demo d'ús quan es crida el fitxer de la classe per separat if __name__ == "__main__": with qgisapp() as app: # Canvas, projecte i bridge canvas = QgsMapCanvas() # canvas.show() project = QgsProject().instance() root = project.layerTreeRoot() bridge = QgsLayerTreeMapCanvasBridge(root, canvas) # llegim un projecte de demo project.read(projecteInicial) # Instanciem la classe QvUbicacions ubicacions = QvUbicacions(canvas) """ Amb aquesta linia: ubicacions.show() es veuria el widget suelto, separat del canvas. Les següents línies mostren com integrar el widget 'ubicacions' com a dockWidget. """