14

I am facing a problem with the new Layout API while implementing a plugin for QGIS 3. Starting point is a layout template in qpt-Format, which contains different elements like (attribute) tables, map, labels and scale-bar. This template is loaded into the Layout Manager with the code below.

During import I want to make dynamic changes to the layout elements like filling tables with new rows or editing the label text.

Any idea on how to address elements of the layout during or after the import, in order to edit the content of labels and tables?

project = QgsProject.instance()
composition = QgsPrintLayout(project)
document = QDomDocument()

# read template content
template_file = open('C:/location/of/template.qpt')
template_content = template_file.read()
template_file.close()
document.setContent(template_content)

# load layout from template and add to Layout Manager
composition.loadFromTemplate(document, QgsReadWriteContext()) 
project.layoutManager().addLayout(composition)

# maybe using QgsLayoutItem???
# layoutItem = composition.itemById("1")
1

2 Answers 2

3

First you need to get the layout as it has been added.

layout = QgsProject.instance().layoutManager().layoutByName("My comp name")

Then with this class can access to your table item by requesting its id if you had set one.

my_table = layout.itemById()

Then working on this particular item like check data or add data. I did'nt use it.

my_table.data(0)
my_table.data(0, "some data")

Hope It gave you some hint to start working.

3

You can manipulate the layout to change reference to layer in the attribute table with below code. The main class involved is QgsLayoutItemAttributeTable

# Kept for other users
# project = QgsProject.instance()
# projectLayoutManager = project.layoutManager()
# layout = projectLayoutManager.layoutByName('your_layout_name')
# In you case
layout = composition

# firstItemContainingAttributeTable = [i for i in layout.items() if isinstance(i, QgsLayoutFrame) and isinstance(i.multiFrame(), QgsLayoutItemAttributeTable)][0]
# or
firstItemContainingAttributeTable = layout.itemById('your_attribute_table_id') # Work if set in original model
layoutItemAttributeTable = firstItemContainingAttributeTable.multiFrame()

existingLayer = project.mapLayersByName('your_layer_name')[0]

# Here we use methods from QgsLayoutItemAttributeTable
layoutItemAttributeTable.setVectorLayer(existingLayer)
layoutItemAttributeTable.resetColumns()
layout.refresh()

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