3

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?

2
  • You can create a duplicate the print composer with the grid and then update the second one with the new data.
    – ahmadhanb
    Commented Dec 5, 2017 at 10:02
  • Yeah I know, but that requires that I won't later update the grid. I would like it to work like the 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.
    – Iamlukesky
    Commented Dec 6, 2017 at 8:30

1 Answer 1

3

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)

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)

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.