def canvasReleaseEvent(self, e): """ After the rectangle is built, here features are selected. """ if QApplication.keyboardModifiers() == Qt.ShiftModifier: firstGeom = self.checkSelectedLayers() self.isEmittingPoint = False r = self.rectangle() if r is None: return layers = self.canvas.layers() for layer in layers: #ignore layers on black list and features that are not vector layers if not isinstance(layer, QgsVectorLayer) or ( self.layerHasPartInBlackList(layer.name())): continue if firstGeom is not None and layer.geometryType() != firstGeom: # if there are features already selected, shift will only get the same type geometry # if more than one ty of geometry is present, only the strongest will be selected continue #builds bbRect and select from layer, adding selection bbRect = self.canvas.mapSettings().mapToLayerCoordinates( layer, r) layer.selectByRect(bbRect, behavior=QgsVectorLayer.AddToSelection) self.rubberBand.hide()
def capture_position(self, event): """ Record the position of the mouse pointer and adjust if keyboard modifier is pressed :type event: qgis.gui.QgsMapMouseEvent """ # adjust dimension on the fly if Shift is pressed if QApplication.keyboardModifiers() == Qt.ShiftModifier: end_point = QgsPointXY(self.toMapCoordinates(event.pos())) rect = QgsRectangle(self.startPoint, end_point) # return if start and endpoint are the same if rect.width() + rect.height() == 0: self.endPoint = self.toMapCoordinates(event.pos()) return if rect.width() > rect.height(): # make height (y) same as width in the correct direction if self.startPoint.y() < end_point.y(): end_point.setY(self.startPoint.y() + rect.width()) else: end_point.setY(self.startPoint.y() - rect.width()) else: # make width (x) same as height in the correct direction if self.startPoint.x() < end_point.x(): end_point.setX(self.startPoint.x() + rect.height()) else: end_point.setX(self.startPoint.x() - rect.height()) self.endPoint = end_point else: self.endPoint = self.toMapCoordinates(event.pos())
def tooltip_text(self, rect): if QApplication.keyboardModifiers() == Qt.ShiftModifier: text = "Size: " + str(round(rect.width(), 2)) else: text = "Size x/y: " + str(round(rect.width(), 2)) + " / " + str( round(rect.height(), 2)) return text
def _set_selection_mode(self, dialog, widget, selection_mode): """ Manage selection mode :param dialog: QDialog where search all checkbox :param widget: QCheckBox that has changed status (QCheckBox) :param selection_mode: "keepPrevious", "keepPreviousUsingShift", "removePrevious" (String) """ # Get QCheckBox check all index = dialog.main_tab.currentIndex() widget_list = dialog.main_tab.widget(index).findChildren(QCheckBox) tab_name = dialog.main_tab.widget(index).objectName() widget_all = dialog.findChild(QCheckBox, f'chk_all_{tab_name}') is_alone = False disable_parent = False key_modifier = QApplication.keyboardModifiers() if key_modifier == Qt.ShiftModifier: disable_parent = True if selection_mode == 'removePrevious' or \ (selection_mode == 'keepPreviousUsingShift' and key_modifier != Qt.ShiftModifier): is_alone = True if widget_all is not None: widget_all.blockSignals(True) tools_qt.set_checked(dialog, widget_all, False) widget_all.blockSignals(False) self._remove_previuos(dialog, widget, widget_all, widget_list) self._set_selector(dialog, widget, is_alone, disable_parent)
def canvasReleaseEvent(self, event): """ Canvas is released. This means: * start digitizing * stop digitizing (create a rectangle * if the Ctrl-modifier is pressed, ask for the rectangle width :param event: coordinates etc. """ if event.button() == Qt.RightButton: self.deactivate() else: mousepos = self.canvas.getCoordinateTransform()\ .toMapCoordinates(event.pos().x(), event.pos().y()) self.rubberband.addPoint(mousepos) if self.firstPoint: # If the first point was set before, we are doing the second one lp1 = self.rubberband.asGeometry().asPolyline()[0] lp2 = self.rubberband.asGeometry().asPolyline()[1] width = 0.2 if QApplication.keyboardModifiers() & Qt.ControlModifier: dlg = QDialog() dlg.setLayout(QGridLayout()) dlg.layout().addWidget(QLabel(self.tr('Enter width'))) txt = QLineEdit('0.2') dlg.layout().addWidget(txt) bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) dlg.layout().addWidget(bb) bb.accepted.connect(dlg.accept) bb.rejected.connect(dlg.reject) if dlg.exec_(): try: width = float(txt.text()) except ValueError: width = 0.2 length = math.sqrt( math.pow(lp1.x() - lp2.x(), 2) + math.pow(lp1.y() - lp2.y(), 2)) xd = lp2.x() - lp1.x() yd = lp2.y() - lp1.y() pt1 = QgsPointXY(lp1.x() + width * (yd / length), lp1.y() - width * (xd / length)) pt2 = QgsPointXY(lp1.x() - width * (yd / length), lp1.y() + width * (xd / length)) pt3 = QgsPointXY(lp2.x() - width * (yd / length), lp2.y() + width * (xd / length)) pt4 = QgsPointXY(lp2.x() + width * (yd / length), lp2.y() - width * (xd / length)) self.geometry = QgsGeometry.fromPolygonXY( [[pt1, pt2, pt3, pt4, pt1]]) self.geometryDigitized.emit() self.firstPoint = mousepos
def canvasReleaseEvent(self, event): self.is_emitting_point = False rectangle = self.get_rectangle() selected_rectangle = None key = QApplication.keyboardModifiers() if event.button() != Qt.LeftButton: self.rubber_band.hide() return # Disconnect signal to enhance process # We will reconnect it when processing last layer of the group if self.mincut: self.mincut.disconnect_signal_selection_changed() if self.parent_manage: self.parent_manage.disconnect_signal_selection_changed() if self.manage_new_psector: self.manage_new_psector.disconnect_signal_selection_changed() for i in range(len(self.layers)): layer = self.layers[i] if i == len(self.layers) - 1: if self.mincut: self.mincut.connect_signal_selection_changed("mincut_connec") if self.parent_manage: self.parent_manage.connect_signal_selection_changed(self.dialog, self.table_object) if self.manage_new_psector: self.manage_new_psector.connect_signal_selection_changed( self.manage_new_psector.dlg_plan_psector, self.table_object) # Selection by rectangle if rectangle: if selected_rectangle is None: selected_rectangle = self.canvas.mapSettings().mapToLayerCoordinates(layer, rectangle) # If Ctrl+Shift clicked: remove features from selection if key == (Qt.ControlModifier | Qt.ShiftModifier): layer.selectByRect(selected_rectangle, layer.RemoveFromSelection) # If Ctrl clicked: add features to selection elif key == Qt.ControlModifier: layer.selectByRect(selected_rectangle, layer.AddToSelection) # If Ctrl not clicked: add features to selection else: layer.selectByRect(selected_rectangle, layer.AddToSelection) # Selection one by one else: event_point = self.snapper_manager.get_event_point(event) result = self.snapper_manager.snap_to_background_layers(event_point) if self.snapper_manager.result_is_valid(): # Get the point. Leave selection self.snapper_manager.get_snapped_feature(result, True) self.rubber_band.hide()
def canvasPressEvent(self, e): """ Method used to build rectangle if shift is held, otherwise, feature select/deselect and identify is done. """ if QApplication.keyboardModifiers() == Qt.ShiftModifier: self.isEmittingPoint = True self.startPoint = self.toMapCoordinates(e.pos()) self.endPoint = self.startPoint self.isEmittingPoint = True self.showRect(self.startPoint, self.endPoint) else: self.isEmittingPoint = False self.createContextMenu(e)
def canvasPressEvent(self, e): """ Method used to build rectangle if shift is held, otherwise, feature select/deselect and identify is done. :param e: (QgsMouseEvent) mouse event. """ if e.button() == QtCore.Qt.LeftButton: self.auxList = [] if QApplication.keyboardModifiers() == QtCore.Qt.ShiftModifier: self.isEmittingPoint = True self.startPoint = self.toMapCoordinates(e.pos()) self.endPoint = self.startPoint self.isEmittingPoint = True self.showRect(self.startPoint, self.endPoint)
def canvasReleaseEvent(self, event): self.is_emitting_point = False rectangle = self._get_rectangle() selected_rectangle = None key = QApplication.keyboardModifiers() if event.button() != Qt.LeftButton: self.rubber_band.hide() return # Disconnect signal to enhance process # We will reconnect it when processing last layer of the group tools_qgis.disconnect_signal_selection_changed() for i, layer in enumerate( self.class_object.layers[self.class_object.feature_type]): if i == len(self.class_object.layers[ self.class_object.feature_type]) - 1: tools_gw.connect_signal_selection_changed(self.class_object, self.dialog, self.table_object, query=self.query) # Selection by rectangle if rectangle: if selected_rectangle is None: selected_rectangle = self.canvas.mapSettings( ).mapToLayerCoordinates(layer, rectangle) # If Ctrl or Ctrl+Shift clicked: remove features to selection if key in (Qt.ControlModifier, (Qt.ControlModifier | Qt.ShiftModifier)): layer.selectByRect(selected_rectangle, layer.RemoveFromSelection) # If not clicked: add features to selection else: layer.selectByRect(selected_rectangle, layer.AddToSelection) # Selection one by one else: event_point = self.snapper_manager.get_event_point(event) result = self.snapper_manager.snap_to_project_config_layers( event_point) if result.isValid(): # Get the point. Leave selection self.snapper_manager.get_snapped_feature(result, True) self.rubber_band.hide()
def canvasReleaseEvent(self, e): """ After the rectangle is built, here features are selected. """ # tool was planned to work on left click if e.button() == QtCore.Qt.LeftButton: layer = self.iface.mapCanvas().currentLayer() if QApplication.keyboardModifiers() == QtCore.Qt.ShiftModifier: self.isEmittingPoint = False r = self.rectangle() if r is None: return bbRect = self.canvas.mapSettings().mapToLayerCoordinates( layer, r) self.rubberBand.hide() #select all stuff layer.selectByIds([]) #portar para o feature handler layer.selectByRect(bbRect, True) #mudar depois para o dsgmothafucka featDict = dict() pointDict = dict() for feat in layer.selectedFeatures(): featDict[feat.id()] = feat pointDict[feat.id()] = feat.geometry() pixelValueDict = self.getPixelValueFromPointDict( pointDict, self.rasterLayer) for idx in pointDict: value = pixelValueDict[idx] if value: self.auxList.append({ 'featId': idx, 'feat': featDict[idx], 'value': value }) else: value, pointGeom = self.getPixelValue(self.rasterLayer) if value: self.auxList.append({'geom': pointGeom, 'value': value}) #create context menu to select attribute if self.auxList: self.createContextMenuOnPosition(e, layer)
def _manage_all(self, dialog, widget_all): status = tools_qt.is_checked(dialog, widget_all) index = dialog.main_tab.currentIndex() widget_list = dialog.main_tab.widget(index).findChildren(QCheckBox) disable_parent = False key_modifier = QApplication.keyboardModifiers() if key_modifier == Qt.ShiftModifier: disable_parent = True for widget in widget_list: if widget_all is not None: if widget == widget_all or widget.objectName( ) == widget_all.objectName(): continue widget.blockSignals(True) tools_qt.set_checked(dialog, widget, status) widget.blockSignals(False) self._set_selector(dialog, widget_all, False, disable_parent)
def select_multiple_features(self, selectGeometry): key = QApplication.keyboardModifiers() # If Ctrl+Shift clicked: remove features from selection if key == (Qt.ControlModifier | Qt.ShiftModifier): behaviour = QgsVectorLayer.RemoveFromSelection # If Ctrl clicked: add features to selection elif key == Qt.ControlModifier: behaviour = QgsVectorLayer.AddToSelection # If Ctrl not clicked: add features to selection else: behaviour = QgsVectorLayer.AddToSelection # Selection for all connec and gully layers layer = self.snapper_manager.layer_connec if layer: layer.selectByRect(selectGeometry, behaviour) layer = self.snapper_manager.layer_gully if layer: layer.selectByRect(selectGeometry, behaviour)
def _select_multiple_features(self, select_geometry): key = QApplication.keyboardModifiers() # If Ctrl+Shift clicked: remove features from selection if key == (Qt.ControlModifier | Qt.ShiftModifier): behaviour = QgsVectorLayer.RemoveFromSelection # If Ctrl clicked: add features to selection elif key == Qt.ControlModifier: behaviour = QgsVectorLayer.AddToSelection # If Ctrl not clicked: add features to selection else: behaviour = QgsVectorLayer.AddToSelection # Selection for all connec and gully layers layer = tools_qgis.get_layer_by_tablename('v_edit_connec') if layer: layer.selectByRect(select_geometry, behaviour) layer = tools_qgis.get_layer_by_tablename('v_edit_gully') if layer: layer.selectByRect(select_geometry, behaviour)
def getCallback(self, e, layer, feature, geomType=None, selectAll=True): """ Gets the callback for an action. :param e: (QMouseEvent) mouse event on canvas. :param layer: (QgsVectorLayer) layer to be treated. :param feature: (QgsFeature) feature to be treated. :param geomType: (int) code indicating layer geometry type. It is retrieved OTF in case it's not given. :return: (tuple-of function_lambda) callbacks for triggered and hovered signals. """ if not geomType: geomType = layer.geometryType() if e.button() == Qt.LeftButton: # line added to make sure the action is associated with current loop value, # lambda function is used with standard parameter set to current loops value. # triggeredAction = lambda t=[layer, feature] : self.setSelectionFeature(t[0], feature=t[1], selectAll=selectAll, setActiveLayer=True) triggeredAction = partial(self.setSelectionFeature, layer=layer, feature=feature, selectAll=selectAll, setActiveLayer=True) hoveredAction = partial(self.createRubberBand, feature=feature, layer=layer, geom=geomType) elif e.button() == Qt.RightButton: selected = (QApplication.keyboardModifiers() == Qt.ControlModifier) if selected: triggeredAction = partial(self.iface.setActiveLayer, layer) hoveredAction = None else: triggeredAction = partial(self.iface.openFeatureForm, layer, feature, showModal=False) hoveredAction = partial(self.createRubberBand, feature=feature, layer=layer, geom=geomType) return triggeredAction, hoveredAction
def canvasMoveEvent(self, e): """ Deals with mouse move event to update the rubber band position in the canvas """ ctrlIsHeld = QApplication.keyboardModifiers() == Qt2.ControlModifier if e.button() != None and not ctrlIsHeld: if self.rotate: # change rotate status self.rotate = False QApplication.restoreOverrideCursor() self.endPoint = self.toMapCoordinates( e.pos() ) elif e.button() != None and ctrlIsHeld \ and self.geometryType == self.tr(u"Square"): # calculate angle between mouse and last rubberband centroid before holding control self.rotAngle = self.rotateRect(self.currentCentroid, e) if not self.rotate: # only override mouse if it is not overriden already QApplication.setOverrideCursor(QCursor(Qt2.BlankCursor)) self.rotate = True if self.geometryType == self.tr(u"Circle"): self.showCircle(self.endPoint) elif self.geometryType == self.tr(u"Square"): self.showRect(self.endPoint, sqrt(self.param)/2, self.rotAngle)
def canvasReleaseEvent(self, event): """ With left click the digitizing is finished """ # Manage if task is already running if hasattr(self, 'connect_link_task') and self.connect_link_task is not None: try: if self.connect_link_task.isActive(): message = "Connect link task is already active!" tools_qgis.show_warning(message) return except RuntimeError: pass if event.button() == Qt.LeftButton: # Get coordinates event_point = self.snapper_manager.get_event_point(event) # Simple selection if not self.dragging: # Snap to connec or gully result = self.snapper_manager.snap_to_project_config_layers( event_point) if not result.isValid(): return # Check if it belongs to 'connec' or 'gully' group layer = self.snapper_manager.get_snapped_layer(result) feature_id = self.snapper_manager.get_snapped_feature_id( result) layer_connec = tools_qgis.get_layer_by_tablename(layer) layer_gully = tools_qgis.get_layer_by_tablename(layer) if layer_connec or layer_gully: key = QApplication.keyboardModifiers() # If Ctrl+Shift is clicked: deselect snapped feature if key == (Qt.ControlModifier | Qt.ShiftModifier): layer.deselect([feature_id]) else: # If Ctrl is not clicked: remove previous selection if key != Qt.ControlModifier: layer.removeSelection() layer.select([feature_id]) # Hide marker self.vertex_marker.hide() # Multiple selection else: # Set valid values for rectangle's width and height if self.select_rect.width() == 1: self.select_rect.setLeft(self.select_rect.left() + 1) if self.select_rect.height() == 1: self.select_rect.setBottom(self.select_rect.bottom() + 1) self._set_rubber_band() self._select_multiple_features(self.selected_rectangle) self.dragging = False # Refresh map canvas tools_gw.reset_rubberband(self.rubber_band) # Force reload dataProvider of layer tools_qgis.set_layer_index('v_edit_link') tools_qgis.set_layer_index('v_edit_vnode') elif event.button() == Qt.RightButton: # Check selected records number_connec_features = 0 layer_connec = tools_qgis.get_layer_by_tablename('v_edit_connec') if layer_connec: number_connec_features += layer_connec.selectedFeatureCount() if number_connec_features > 0 and QgsProject.instance( ).layerTreeRoot().findLayer(layer_connec).isVisible(): message = "Number of features selected in the group of" title = "Connect to network" answer = tools_qt.show_question(message, title, parameter='connec: ' + str(number_connec_features)) if answer: # Create link self.connect_link_task = GwConnectLink( "Connect link", self, 'connec', layer_connec) QgsApplication.taskManager().addTask( self.connect_link_task) QgsApplication.taskManager().triggerTask( self.connect_link_task) else: self.manage_gully_result() else: self.manage_gully_result() if number_connec_features == 0 or QgsProject.instance( ).layerTreeRoot().findLayer(layer_connec).isVisible() is False: self.cancel_map_tool()
def canvasReleaseEvent(self, event): if not self.mouse_clicked: return if event.button() == Qt.LeftButton: self.mouse_clicked = False # Snapped: one element selected if self.snap_results is not None: snapped_ft = vector_utils.get_feats_by_id( self.snap_results.layer(), self.snap_results.featureId())[0] # snapped_layer = self.snap_results[0].layer snapped_layer = self.snap_results.layer() modifiers = QApplication.keyboardModifiers() if modifiers == Qt.ShiftModifier: selected_ft_ids = snapped_layer.selectedFeatureIds() selected_ft_ids.append(snapped_ft.id()) snapped_layer.select(selected_ft_ids) else: for layer in self.iface.mapCanvas().layers(): if layer.id() == self.params.junctions_vlay.id() or \ layer.id() == self.params.reservoirs_vlay.id() or \ layer.id() == self.params.tanks_vlay.id() or \ layer.id() == self.params.pipes_vlay.id() or \ layer.id() == self.params.pumps_vlay.id() or \ layer.id() == self.params.valves_vlay.id(): layer.removeSelection() snapped_layer.select(snapped_ft.id()) # Not snapped: rectangle else: # There is a rubber band box if self.rubber_band.numberOfVertices() > 1: rubber_band_rect = self.rubber_band.asGeometry( ).boundingBox() for layer in self.iface.mapCanvas().layers(): if layer.id() == self.params.junctions_vlay.id() or\ layer.id() == self.params.reservoirs_vlay.id() or\ layer.id() == self.params.tanks_vlay.id() or\ layer.id() == self.params.pipes_vlay.id() or\ layer.id() == self.params.pumps_vlay.id() or\ layer.id() == self.params.valves_vlay.id(): layer.selectByIds([]) if Qgis.QGIS_VERSION_INT < 21600: layer.select(rubber_band_rect, False) else: layer.selectByRect(rubber_band_rect, False) self.rubber_band.reset(Qgis.Polygon) # No rubber band: clear selection else: self.params.junctions_vlay.removeSelection() self.params.reservoirs_vlay.removeSelection() self.params.tanks_vlay.removeSelection() self.params.pipes_vlay.removeSelection() self.params.pumps_vlay.removeSelection() self.params.valves_vlay.removeSelection() self.iface.mapCanvas().refresh()
def canvasReleaseEvent(self, event): """ With left click the digitizing is finished """ if event.button() == Qt.LeftButton: # Get coordinates event_point = self.snapper_manager.get_event_point(event) # Simple selection if not self.dragging: # Snap to connec or gully result = self.snapper_manager.snap_to_background_layers( event_point) if not self.snapper_manager.result_is_valid(): return # Check if it belongs to 'connec' or 'gully' group layer = self.snapper_manager.get_snapped_layer(result) feature_id = self.snapper_manager.get_snapped_feature_id( result) exist_connec = self.snapper_manager.check_connec_group(layer) exist_gully = self.snapper_manager.check_gully_group(layer) if exist_connec or exist_gully: key = QApplication.keyboardModifiers() # If Ctrl+Shift is clicked: deselect snapped feature if key == (Qt.ControlModifier | Qt.ShiftModifier): layer.deselect([feature_id]) else: # If Ctrl is not clicked: remove previous selection if key != Qt.ControlModifier: layer.removeSelection() layer.select([feature_id]) # Hide marker self.vertex_marker.hide() # Multiple selection else: # Set valid values for rectangle's width and height if self.select_rect.width() == 1: self.select_rect.setLeft(self.select_rect.left() + 1) if self.select_rect.height() == 1: self.select_rect.setBottom(self.select_rect.bottom() + 1) self.set_rubber_band() self.select_multiple_features(self.selected_rectangle) self.dragging = False # Refresh map canvas self.rubber_band.reset() elif event.button() == Qt.RightButton: # Check selected records number_features = 0 layer = self.snapper_manager.layer_connec if layer: number_features += layer.selectedFeatureCount() if number_features > 0: message = "Number of features selected in the 'connec' group" title = "Interpolate value - Do you want to update values" answer = self.controller.ask_question( message, title, parameter=str(number_features)) if answer: # Create link self.link_selected_features('connec', layer) layer = self.snapper_manager.layer_gully if layer: # Check selected records number_features = 0 number_features += layer.selectedFeatureCount() if number_features > 0: message = "Number of features selected in the 'gully' group" title = "Interpolate value - Do you want to update values" answer = self.controller.ask_question( message, title, parameter=str(number_features)) if answer: # Create link self.link_selected_features('gully', layer) # Force reload dataProvider of layer self.controller.indexing_spatial_layer('v_edit_link') self.controller.indexing_spatial_layer('v_edit_vnode')
def canvasReleaseEvent(self, e: QgsMapMouseEvent) -> None: self.isEmittingPoint = False self.rubberBand.hide() self.polygonCreated.emit(self.startPoint, self.endPoint, QApplication.keyboardModifiers())
def createContextMenu(self, e): """ Creates the context menu for overlapping layers. :param e: mouse event caught from canvas. """ selected = (QApplication.keyboardModifiers() == Qt.ControlModifier) if selected: firstGeom = self.checkSelectedLayers() # setting a list of features to iterate over layerList = self.getPrimitiveDict(e, hasControlModifier=selected) layers = [] for key in layerList: layers += layerList[key] if layers: rect = self.getCursorRect(e) lyrFeatDict = dict() for layer in layers: if not isinstance(layer, QgsVectorLayer): continue geomType = layer.geometryType() # iterate over features inside the mouse bounding box bbRect = self.canvas.mapSettings().mapToLayerCoordinates( layer, rect) for feature in layer.getFeatures(QgsFeatureRequest(bbRect)): geom = feature.geometry() if geom: searchRect = self.geometryHandler.reprojectSearchArea( layer, rect) if selected: # if Control was held, appending behaviour is different if not firstGeom: firstGeom = geomType elif firstGeom > geomType: firstGeom = geomType if geomType == firstGeom and geom.intersects( searchRect): # only appends features if it has the same geometry as first selected feature if layer in lyrFeatDict: lyrFeatDict[layer].append(feature) else: lyrFeatDict[layer] = [feature] else: if geom.intersects(searchRect): if layer in lyrFeatDict: lyrFeatDict[layer].append(feature) else: lyrFeatDict[layer] = [feature] lyrFeatDict = self.filterStrongestGeometry(lyrFeatDict) if lyrFeatDict: moreThanOneFeat = len(list(lyrFeatDict.values())) > 1 or len( list(lyrFeatDict.values())[0]) > 1 if moreThanOneFeat: # if there are overlapping features (valid candidates only) selectedFeaturesDict, notSelectedFeaturesDict = self.checkSelectedFeaturesOnDict( menuDict=lyrFeatDict) self.setContextMenuStyle( e=e, dictMenuSelected=selectedFeaturesDict, dictMenuNotSelected=notSelectedFeaturesDict) else: layer = list(lyrFeatDict.keys())[0] feature = lyrFeatDict[layer][0] selected = ( QApplication.keyboardModifiers() == Qt.ControlModifier) if e.button() == Qt.LeftButton: # if feature is selected, we want it to be de-selected self.setSelectionFeature(layer=layer, feature=feature, selectAll=False, setActiveLayer=True) elif selected: self.iface.setActiveLayer(layer) else: self.iface.openFeatureForm(layer, feature, showModal=False)