I'm using python to command the print composer and export images/pdf (https://opensourceoptions.com/blog/pyqgis-create-and-print-a-map-layout-with-python/)
I'm looping through layers by name to export each layer. It works quite well for all but it's messy if layers are next to each other as I want to only show one. I need and want to use the themes that I've set up but I can't find a way to bring them to Print Composer.
I can change the theme using iface.mapCanvas().setTheme('green')
, but this doesn't affect the layout in the Print Composer.
How can I use a different theme for each layouts via Python? Can it be done through QgsMapThemeCollection and applyTheme()?
from qgis.PyQt import QtGui
layernames = [layer.name() for layer in QgsProject.instance().mapLayers().values()]
for each in layernames:
layers = QgsProject.instance().mapLayersByName(each)
print(layers)
layer = layers[0]
project = QgsProject.instance()
manager = project.layoutManager()
layoutName = each + "_layout"
iface.mapCanvas().setTheme(each)
layouts_list = manager.printLayouts()
#remove any duplicate layouts
for layout in layouts_list:
if layout.name() == layoutName:
manager.removeLayout(layout)
layout = QgsPrintLayout(project)
layout.initializeDefaults()
layout.setName(layoutName)
manager.addLayout(layout)
#create map item in the layout
map = QgsLayoutItemMap(layout)
map.setRect(20, 20, 20, 20)
#set the map extent
ms = QgsMapSettings()
ms.setLayers([layer]) #set layers to be mapped
rect = QgsRectangle(ms.fullExtent())
rect.scale(1.6)
ms.setExtent(rect)
map.setExtent(rect)
map.setBackgroundColor(QColor(255, 255, 255, 0))
layout.addLayoutItem(map)
map.attemptMove(QgsLayoutPoint(5, 20, QgsUnitTypes.LayoutMillimeters))
map.attemptResize(QgsLayoutSize(200, 180, QgsUnitTypes.LayoutMillimeters))
legend = QgsLayoutItemLegend(layout)
legend.setTitle("Legend")
layerTree = QgsLayerTree()
layerTree.addLayer(layer)
legend.model().setRootGroup(layerTree)
layout.addLayoutItem(legend)
legend.attemptMove(QgsLayoutPoint(245, 5, QgsUnitTypes.LayoutMillimeters))
scalebar = QgsLayoutItemScaleBar(layout)
scalebar.setStyle('Line Ticks Up')
scalebar.setUnits(QgsUnitTypes.DistanceKilometers)
scalebar.setNumberOfSegments(4)
scalebar.setNumberOfSegmentsLeft(0)
scalebar.setUnitsPerSegment(0.5)
scalebar.setLinkedMap(map)
scalebar.setUnitLabel('km')
scalebar.setFont(QFont('Arial', 14))
scalebar.update()
layout.addLayoutItem(scalebar)
scalebar.attemptMove(QgsLayoutPoint(200, 190, QgsUnitTypes.LayoutMillimeters))
title = QgsLayoutItemLabel(layout)
title.setText(each)
title.setFont(QFont('Arial', 24))
title.adjustSizeToText()
layout.addLayoutItem(title)
title.attemptMove(QgsLayoutPoint(10, 5, QgsUnitTypes.LayoutMillimeters))
#checking theme names can be accessed:
themes = QgsProject.instance().mapThemeCollection().mapThemes()
print(themes)
layout = manager.layoutByName(layoutName)
exporter = QgsLayoutExporter(layout)
fn = 'C:/export/' + each + '.png'
exporter.exportToImage(fn, QgsLayoutExporter.ImageExportSettings())
#exporter.exportToPdf(fn, QgsLayoutExporter.PdfExportSettings())