def testSignals(self): QgsProject.instance().clear() m = QgsMapLayerComboBox() l1 = QgsVectorLayer( "Point?crs=EPSG:3111&field=fldtxt:string&field=fldint:integer", 'layer 1', "memory") QgsProject.instance().addMapLayer(l1) l2 = QgsVectorLayer( "Polygon?crs=EPSG:3111&field=fldtxt:string&field=fldint:integer", 'lAyEr 2', "memory") QgsProject.instance().addMapLayer(l2) spy = QSignalSpy(m.layerChanged) m.setLayer(l2) self.assertEqual(len(spy), 1) self.assertEqual(m.currentLayer(), l2) m.setLayer(l1) self.assertEqual(len(spy), 2) self.assertEqual(m.currentLayer(), l1) # no signal if same layer m.setLayer(l1) self.assertEqual(len(spy), 2) m.setAllowEmptyLayer(True) m.setLayer(None) self.assertEqual(len(spy), 3) self.assertIsNone(m.currentLayer()) m.setLayer(None) self.assertEqual(len(spy), 3) self.assertIsNone(m.currentLayer()) m.setLayer(l1) self.assertEqual(len(spy), 4) self.assertEqual(m.currentLayer(), l1)
def testAdditionalLayers(self): QgsProject.instance().clear() l1 = create_layer('l1') l2 = create_layer('l2') QgsProject.instance().addMapLayers([l1, l2]) m = QgsMapLayerComboBox() self.assertEqual(m.count(), 2) l3 = create_layer('l3') l4 = create_layer('l4') m.setAdditionalLayers([l3, l4]) self.assertEqual(m.count(), 4) m.setAdditionalItems(['a', 'b']) self.assertEqual(m.count(), 6) self.assertEqual(m.itemText(0), 'l1') self.assertEqual(m.itemText(1), 'l2') self.assertEqual(m.itemText(2), 'l3') self.assertEqual(m.itemText(3), 'l4') self.assertEqual(m.itemText(4), 'a') self.assertEqual(m.itemText(5), 'b') m.setAllowEmptyLayer(True) self.assertEqual(m.count(), 7) self.assertFalse(m.itemText(0)) self.assertEqual(m.itemText(1), 'l1') self.assertEqual(m.itemText(2), 'l2') self.assertEqual(m.itemText(3), 'l3') self.assertEqual(m.itemText(4), 'l4') self.assertEqual(m.itemText(5), 'a') self.assertEqual(m.itemText(6), 'b') l3.deleteLater() QCoreApplication.sendPostedEvents(None, QEvent.DeferredDelete) self.assertEqual(m.count(), 6) self.assertFalse(m.itemText(0)) self.assertEqual(m.itemText(1), 'l1') self.assertEqual(m.itemText(2), 'l2') self.assertEqual(m.itemText(3), 'l4') self.assertEqual(m.itemText(4), 'a') self.assertEqual(m.itemText(5), 'b') l5 = create_layer('l5') l6 = create_layer('l6') m.setAdditionalLayers([l5, l6, l4]) self.assertEqual(m.count(), 8) self.assertFalse(m.itemText(0)) self.assertEqual(m.itemText(1), 'l1') self.assertEqual(m.itemText(2), 'l2') self.assertEqual(m.itemText(3), 'l4') self.assertEqual(m.itemText(4), 'l5') self.assertEqual(m.itemText(5), 'l6') self.assertEqual(m.itemText(6), 'a') self.assertEqual(m.itemText(7), 'b') m.setAdditionalLayers([l5, l4]) self.assertEqual(m.count(), 7) self.assertFalse(m.itemText(0)) self.assertEqual(m.itemText(1), 'l1') self.assertEqual(m.itemText(2), 'l2') self.assertEqual(m.itemText(3), 'l4') self.assertEqual(m.itemText(4), 'l5') self.assertEqual(m.itemText(5), 'a') self.assertEqual(m.itemText(6), 'b') QgsProject.instance().removeMapLayers([l1.id(), l2.id()]) self.assertEqual(m.count(), 5) self.assertFalse(m.itemText(0)) self.assertEqual(m.itemText(1), 'l4') self.assertEqual(m.itemText(2), 'l5') self.assertEqual(m.itemText(3), 'a') self.assertEqual(m.itemText(4), 'b')
class VertexComparePlugin(QObject): """QGIS Plugin Implementation.""" def __init__(self, iface: QgisInterface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ super().__init__() # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QgsApplication.locale() locale_path = os.path.join(self.plugin_dir, 'i18n', '{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) QCoreApplication.installTranslator(self.translator) self.toolbar = None self.layer_combo = None self.actions = [] self.dock = None self.vertex_highlighter = VertexHighlighterManager() self.selection_handler = SelectionHandler(self) self.show_vertices_action = None self.show_topology_action = None self.show_dock_action = None @staticmethod def tr(message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('VertexCompare', message) def initProcessing(self): """Create the Processing provider""" def initGui(self): """Creates application GUI widgets""" self.initProcessing() self.dock = VertexDockWidget(self.iface.mapCanvas()) self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dock) self.dock.setUserVisible(False) self.toolbar = QToolBar(self.tr('Vertex Compare Toolbar')) self.toolbar.setObjectName('vertexCompareToolbar') self.iface.addToolBar(self.toolbar) self.layer_combo = QgsMapLayerComboBox() self.layer_combo.setAllowEmptyLayer(True, self.tr('Disabled')) self.layer_combo.setFilters(QgsMapLayerProxyModel.PolygonLayer | QgsMapLayerProxyModel.LineLayer) self.layer_combo.setMinimumWidth( QFontMetrics(self.layer_combo.font()).width('x') * 40) self.layer_combo.setCurrentIndex(0) self.layer_combo.layerChanged.connect(self._set_layer) self.toolbar.addWidget(self.layer_combo) self.show_vertices_action = QAction(self.tr("Show Vertex Numbers"), self) self.show_vertices_action.setIcon( GuiUtils.get_icon('show_vertex_numbers.svg')) self.show_vertices_action.setCheckable(True) self.show_vertices_action.setEnabled(False) self.actions.append(self.show_vertices_action) self.toolbar.addAction(self.show_vertices_action) self.show_vertices_action.toggled.connect( self.vertex_highlighter.set_visible) self.show_topology_action = QAction(self.tr("Compare Vertices"), self) self.show_topology_action.setIcon(GuiUtils.get_icon('topology.svg')) self.show_topology_action.setCheckable(True) self.actions.append(self.show_topology_action) self.toolbar.addAction(self.show_topology_action) self.show_topology_action.toggled.connect( self.vertex_highlighter.set_topological) self.show_dock_action = QAction(self.tr('Show Vertices'), parent=self.toolbar) self.show_dock_action.setIcon(GuiUtils.get_icon('vertex_table.svg')) self.toolbar.addAction(self.show_dock_action) self.actions.append(self.show_dock_action) self.dock.setToggleVisibilityAction(self.show_dock_action) self.selection_handler.selection_changed.connect( self._selection_changed) self.dock.label_filter_changed.connect(self.vertex_highlighter.redraw) self.dock.vertex_symbol_changed.connect(self.vertex_highlighter.redraw) self.dock.vertex_text_format_changed.connect( self.vertex_highlighter.redraw) self.dock.selected_vertex_changed.connect( self.vertex_highlighter.set_selected_vertex) def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for a in self.actions: a.deleteLater() self.actions = [] if self.toolbar is not None: self.toolbar.deleteLater() self.toolbar = None if self.dock is not None: self.dock.deleteLater() self.dock = None def _set_layer(self, layer: Optional[QgsVectorLayer]): """ Triggered when the selected layer is changed """ self.selection_handler.set_layer(layer) self.vertex_highlighter.set_layer(layer) self.show_vertices_action.setEnabled(layer is not None) if not self.show_vertices_action.isEnabled(): self.show_vertices_action.setChecked(False) else: self.show_vertices_action.setChecked(True) self.dock.set_selection( layer, layer.selectedFeatureIds() if layer is not None else []) def _selection_changed(self, layer: Optional[QgsVectorLayer], selection: List[int]): """ Triggered when the watched layer's selection is changed """ self.dock.set_selection(layer, selection)