1

I wrote a script that automate the production of an atlas layout with PyQGIS 3 that works well but it remains a detail I can't figure out.

Each page of my atlas contains a map zoomed on a particular extent, and an attribute table presenting some key informations on the features visible on the map.

I would like to sort the attribute table according to the values of one attribute.

I know how to do it for a text table:

tab.sort(key=lambda x:x[0]) # to sort from the 1st column

But it doesn't work for the QgsLayoutItemAttributeTable class that has no attribute sort

I first thougth to "convert" my attribute table to a text table, but I am sure there is an easier and faster way to sort it. Like the attribute table change on each page, it will make the script too heavy for nothing.

UPDATE The following code return a sorted attribute table displayed on my layout

project = QgsProject.instance()
manager = project.layoutManager()
layoutName = "Atlas"
layouts_list = manager.printLayouts()
for layout in layouts_list:
    if layout.name() == layoutName:
        manager.removeLayout(layout)

layout = QgsPrintLayout(project)
layout.initializeDefaults()

layout.setName(layoutName)

manager.addLayout(layout)

pdf = project.mapLayersByName('plan_de_ferme')[0]
pdf_table = QgsLayoutItemAttributeTable.create(layout)
pdf_table.setVectorLayer(pdf)
pdf_fields = ['champ','sup','supepnd']
pdf_table.setDisplayedFields(pdf_fields, True)
layout.addMultiFrame(pdf_table)
frame2 = QgsLayoutFrame(layout, pdf_table)
frame2.attemptResize(QgsLayoutSize(60.6, 153.3),True)
frame2.attemptMove(QgsLayoutPoint(213, 30.73, QgsUnitTypes.LayoutMillimeters))
pdf_table.addFrame(frame2)

tblCol = QgsLayoutTableColumn()
tblCol.setAttribute('champ')
tblCol.setSortOrder(0) # 0 = Asc, 1 Desc
pdf_table.setSortColumns([tblCol])
layout.refresh()

1 Answer 1

2

You can find below a sample to do sorting using the "PyQGIS way" instead of the Python way.

project = QgsProject.instance()
projectLayoutManager = project.layoutManager()

layout = projectLayoutManager.layoutByName('Your layout name')
# You need to select in the layout GUI an existing
# "QgsLayoutItemAttributeTable" (in fact, insertion
# of a QgsLayoutItemAttributeTable insert it within
# a QgsLayoutFrame)
firstItemSelected = layout.selectedLayoutItems()[0] # QgsLayoutFrame

frame = firstItemSelected.multiFrame() # Your QgsLayoutItemAttributeTable

# Part to do the sort using QGIS mecanism. Also available in the GUI of
# the layout (part "Item Properties", "Main properties", click on
# button "Attributes" and see "Sorting")

tblCol = QgsLayoutTableColumn()
tblCol.setAttribute('NAME') # First column name in your case. You can also put an expression
tblCol.setSortOrder(0) # 0 = Asc, 1 Desc

frame.setSortColumns([tblCol])
1
  • Thank you Thomas, that works great ! Commented Feb 10, 2021 at 21:56

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.