2

I have created a layer filter Expression to get specific results query from my layer and I add these results in a list widget using PyQt.

My Expression and my add to list widget work fine (I print correct ids and I see those ids in list widget).

However, if I want to zoom to a feature using double click signal in the list widget then it zooms to the wrong features (features where my Expression is False). Any idea what I have wrong in my code?

My code:

__init__ 
self.connect(self.ui.listWidget, SIGNAL("itemDoubleClicked (QListWidgetItem 
*)"), self.Zoomt) 

My filter:

def myfilter(self): 
    layer = QgsMapLayerRegistry.instance().mapLayersByName("mylayrt")[0] 
    request = QgsFeatureRequest().setFilterExpression('"name" =\'{0}\''.format(myname)) 
    for feature in layer.getFeatures(request): 
        print str(feature.attribute("myid")) 
        self.ui.listWidget.addItem(str(feature.attribute("myid"))) 

Result print:

1 
42 
43 
44 
45 
96 
111 
304 
458 
508 
579 
602 
606 
646 

That is ids are added correctly in the list widget (14 ids).

Zoom button:

def Zoomt(self): 
    Vl_Gs = QgsMapLayerRegistry.instance().mapLayersByName("mylayer")[0] 
    Vl_Gs.removeSelection 
    Vl_Gs.setSelectedFeatures([self.ui.listWidget.currentRow()]) 
    self.mapCanvas.zoomToSelected(Vl_Gs) 

Zoom ids (take first 14 from my layer):

0 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 

Ids len number is correct but the ids zoom is wrong, why?

2
  • I think Vl_Gs.removeSelection should be Vl_Gs.removeSelection()
    – Joseph
    Commented Jan 22, 2018 at 11:00
  • @Joseph i change this code line but i have some problem,any other idea ?
    – hellas
    Commented Jan 22, 2018 at 16:48

1 Answer 1

2

When setting selected features, you will need the id of those features. You're using Vl_Gs.setSelectedFeatures([self.ui.listWidget.currentRow()]) which only gets the index value of the listwidget row. What you could do is create another feature request and match the feature's attribute with the selected item. Maybe something like:

def Zoomt(self): 
    Vl_Gs = QgsMapLayerRegistry.instance().mapLayersByName("mylayer")[0] 
    expr = QgsExpression('"name" =\'{0}\''.format(self.ui.listWidget.currentItem().text()))
    selection = Vl_Gs.getFeatures(QgsFeatureRequest(expr))
    ids = [s.id() for s in selection]
    Vl_Gs.selectByIds(ids)
    self.mapCanvas().zoomToSelected(Vl_Gs)

Note that the method QgsVectorLayer::setSelectedFeatures() has been depreciated in 2.18 and you should instead use QgsVectorLayer::selectByIds().


Edit:

If using QGIS < 2.16, use setSelectedFeatures() (which you have originally used) so replace the following line:

Vl_Gs.selectByIds(ids) 

with

Vl_Gs.setSelectedFeatures(ids)
5
  • you are correct about id,now if i print self.ui.listWidget.currentItem().text() then i take correct feature id..but not work your code i take error : AttributeError:QgsVectorLayer' object has no attribute 'selectByIds, any idea where i have wrong ?i use QGIS 2.14
    – hellas
    Commented Jan 23, 2018 at 21:07
  • 1
    i think so selectByIds() not exist in QGIS 2.14
    – hellas
    Commented Jan 23, 2018 at 21:30
  • 1
    @hellas - Yes you are correct, selectByIds() is only availablel from QGIS 2.16 onwards. Stick with your original line: setSelectedFeatures(ids) :)
    – Joseph
    Commented Jan 24, 2018 at 10:41
  • all work fine now,but i have one question about zoot function.why use expr = QgsExpression('"name" =\'{0}\''.format(self.ui.listWidget.currentItem().text())) again because if i print self.ui.listWidget.currentItem().text() then i take correct id
    – hellas
    Commented Jan 26, 2018 at 23:16
  • @hellas - It was just to ensure you get the correct value from the list widget. You could modify your code so that you only need to use that line once :)
    – Joseph
    Commented Jan 29, 2018 at 10:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.