Skip to main content
added 940 characters in body
Source Link
ThomasG77
  • 31.2k
  • 1
  • 55
  • 95

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)

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)
Source Link
ThomasG77
  • 31.2k
  • 1
  • 55
  • 95

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 with newLayoutItemMapGrid = QgsLayoutItemMapGrid('name', yourlayoutitemmap) ans set your particular config
  • by copying it from another layout (previous code already show how to access it)