Getting an ordered list of ids of selected objects using PyQGIS
Use this script:
selection = []
def selection_changed(selected, deselected, clearAndSelect):
global selection
# If the user deselects feature(s), remove ID's from list
if deselected:
selection = [ID for ID in selection if ID not in deselected]
print(f"Selection: {selection}")
else:
# get newly selected IDs
new_selected = list(set(selected) - set(selection))
print(new_selected)
# if multiple objects are selected, deselect them and warn the user
if len(new_selected) > 1:
print("Select just one item!")
iface.activeLayer().deselect(new_selected)
return
# if one object is selected, add its ID to list
selection.extend(new_selected)
print(f"Selection: {selection}")
iface.activeLayer().selectionChanged.connect(selection_changed)
Note that selectionChanged
doesn't work all layers. I mean after running the script, if you select another layer, you should run the script for that layer, too.
I do something similiar in my stripchartplugin at https://github.com/sickel/qgisstripchart/blob/master/stripchart.py
When I initiate, I define an array:
self.selectlines=[]
I set up a signal:
self.iface.mapCanvas().selectionChanged.connect(self.markselected)
and in self.markselected I can do
sels=self.view.layer.selectedFeatures()
where self.view.layer
is set elsewhere and is the layer I am working on and compare sels
with self.selectlines
For my purposes, the sorting of the lists does not matter, but what you can do is probably to
check the length of
sels
compared toself.selectlines
, if it is more than one longer, thrown an error - if it is shorter, well you have to decide. (see below)if len(sels) - len(self.selectlines) == 1
, check which elements insels
that is not inself.selectlines
and append it.
The difficulty comes in if a user does something unexpected - they always will do - e.g. if a user has selected 10 items, deselects everything and reselects 11 other items - you need to be able to handle that.
(the solution will probably be to check if there is more than one item that is in sels
that is not in self.selectlines
, throw an error if so - but how tho check it is more general Python than QGIS)