Let's say I have a print composer with two maps. On one I define a grid. Can I copy/paste this grid over to the other map in any way?
1 Answer
A good starting point sample with explanations
from qgis.core import QgsProject, QgsLayoutItemMap
project = QgsProject.instance()
manager = project.layoutManager()
layout = manager.layoutByName('yourlayoutname') # Your layout name
# Useful if you need to loop on layouts, unused here, just mentioned
layouts_list = manager.printLayouts()
# If only one map within the layout
layoutItemMap = [i for i in layout.items() if isinstance(i, QgsLayoutItemMap)][0]
# Could also use the following if you defined an id 'mymap' for the QgsLayoutItemMap (commented here)
# layoutItemMap = layout.itemById('mymap')
# How to access to grid(s) related to the map
# Get the first grid, a QgsLayoutItemMapGrid
grid1= layoutItemMap.grid()
# Or get QgsLayoutItemMapGridStack, a list like of QgsLayoutItemMapGrid with it particular methods
gridstack = layoutItemMap.grids()
# Work, get all grids as a list of QgsLayoutItemMapGrid and loop
for grid in gridstack.asList():
print(grid)
# As a reminder while experimenting: failed with crash on my computer (to confirmed for other users)
# for grid in gridstack:
# print(grid)
You can add or remove new grid to gridstack
by using methods from https://qgis.org/pyqgis/3.10/core/QgsLayoutItemMapGridStack.html like addGrid
or removeGrid
You can know manipulate each grid using the methods documented in https://qgis.org/pyqgis/3.10/core/QgsLayoutItemMapGrid.html
For your purpose, you need to loop on layouts from layouts_list
, then access to their grids and add the one you want:
- by creating a new
QgsLayoutItemMapGrid
withnewLayoutItemMapGrid = QgsLayoutItemMapGrid('name', yourlayoutitemmap)
ans set your particular config - by copying it from another layout (previous code already show how to access it)
You can find out another excerpt to make this copy (considering you've already executed the initial part of the code)
from qgis.PyQt.QtXml import QDomDocument
from qgis.core import QgsLayoutItemMapGrid, QgsReadWriteContext
doc = QDomDocument('Clipboard')
element = doc.createElement('Copied items')
context = QgsReadWriteContext()
grid1.writeXml(element, doc, context)
composermapGrids = element.elementsByTagName('ComposerMapGrid')
if (composermapGrids.count() == 1):
item_node = composermapGrids.at(0)
item_node.toElement().removeAttribute('uuid')
item_node.toElement().setAttribute('name', 'yourNewGridName')
# Create new grid, the name will be overwrited so no need to care...
newLayoutItemMapGrid = QgsLayoutItemMapGrid('Whatever', layoutItemMap)
# Copy from previous grid
newLayoutItemMapGrid.readXml(element.firstChild().toElement(), doc, context)
# Add the copied grid to gridstack
gridstack.addGrid(newLayoutItemMapGrid)
copy/paste style
feature. Or at least be able to get/set the grid definition in plain text so I can save a grid template.