3

My QGIS 3.40.14/Python 3.12.12 code is creating a memory layer with a bunch of point features:

fields = QgsFields()
fields.append(QgsField('number', QVariant.Int)) #number should be unique within a line
fields.append(QgsField('linename', QVariant.String)) #Same name for all points in a line
fields.append(QgsField('date', QVariant.Int))
fields.append(QgsField('time', QVariant.Int))
    
self.vectorlayer = QgsMemoryProviderUtils.createMemoryLayer("points", fields, Qgis.WkbType.Point, self.epsg)

for p in points:
    pointfeature = QgsFeature(fields)
    pointfeature.setGeometry(QgsGeometry.fromPoint(QgsPoint(p.x, p.y, p.z)))
    pointfeature.setAttributes([p.number, p.linename, p.date, p.time])

...

When the map isn't zoomed in, it's hard to click on a specific point, so I usually right-click and pick the point I want to click on in the menu. The problem: For some reason, it sets the "linename" as a default value, and since it's the same for all points within a line, it's impossible to distinguish between the points in that menu. If I remove this String attribute, then it uses the first one in the list, which is the number.

The "Identify Results" window looks like this:

Screenshot of the "Identify Results" panel

How do I set the number as the top attribute for this specific layer instead?

This answer explains how to choose a default field in the layer settings, but I want to set it in code.

I already tried this, as suggested here, but it didn't change anything.

defval = QgsDefaultValue()
defval.setExpression("'number'")
self.vectorlayer.setDefaultValueDefinition(0, defval)

1 Answer 1

3

QgsDefaultValue doesn't control the "top" attribute shown in the right-click identify menu, that's for default fill values in new features. If I understood your issue correctly, you're looking for the display expression of the layer, which is what QGIS uses to label features in the identify menu, the locator, relation references, etc.

You can set it with setDisplayExpression():

lyr = iface.activeLayer()
lyr.setDisplayExpression('"Name"')
was is
was is

This one will also work:

lyr.setDisplayExpression('Name')

However, without the double-quotes, QGIS would interpret the number as a literal string or keyword rather than a field reference. Therefore, the quoting convention is necessary: the outer quotes are Python, the inner double-quotes are QGIS expression syntax for a field name.

print(lyr.displayExpression())  # should print: "Name" or just Name

PyQGIS takes a plain QString, just the expression text as a Python str. The documentation says "Uses QgsExpression", meaning it internally parses the string as a QgsExpression, not that you pass a QgsExpression object.

setDefaultValueDefinition() sets the value that is pre-populated when a new feature is created in edit mode; it does not affect how features are identified or displayed in the UI.

The display expression is a separate layer-level property that QGIS falls back to heuristically (it picks the first string field, which is why linename was winning before).


References:

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.