3

I'm creating a standalone PyQGIS application with a function to print a layout with all layers on the existing canvas.

Here is the current code for printing all the layers on canvas onto a layout, and then exporting them into a pdf:

def createLayout(Main):
    layers = Main.canvas.layers()
    project = QgsProject.instance()
    manager = project.layoutManager()
    layoutName = 'Layout1'
    layouts_list = manager.printLayouts()
    for layout in layouts_list:
        if layout.name() == layoutName:
            manager.removeLayout(layout)
    layout = QgsPrintLayout(project)
    layout.initializeDefaults()
    layout.setName(layoutName)
    manager.addLayout(layout)

    map = QgsLayoutItemMap(layout)
    map.setRect(20, 20, 20, 20)

    ms = QgsMapSettings()
    ms.setLayers(layers)
    print(ms.layerIds())
    print(layers)
    rect = QgsRectangle(ms.fullExtent())
    rect.scale(1.0)
    ms.setExtent(Main.canvas.extent())
    map.setExtent(Main.canvas.extent())
    layout.addLayoutItem(map)

    map.attemptMove(QgsLayoutPoint(5, 20, QgsUnitTypes.LayoutMillimeters))
    map.attemptResize(QgsLayoutSize(180, 180, QgsUnitTypes.LayoutMillimeters))

    # This exports a Print Layout as an image
    layout = manager.layoutByName(layoutName)

    # This creates a QgsLayoutExporter object
    exporter = QgsLayoutExporter(layout)

    # This exports a pdf of the layout object
    exporter.exportToPdf('C:\\Users\\seteg\\Desktop\\test\\testPDF.pdf', QgsLayoutExporter.PdfExportSettings())

I was following this tutorial https://www.youtube.com/watch?v=h8tNuzHqK2I and it works for the most part. Problem is, in my canvas, there should be two layers, an shp layer and a tiff layer. The shp file should be on top of the tiff file.

This is the output of print(layers):

[<QgsMapLayer: '0-Boundary' (ogr)>, <QgsMapLayer: '1-1-Slope' (gdal)>]

As mentioned in the API for setLayers:(https://qgis.org/pyqgis/3.0/core/Map/QgsMapSettings.html#qgis.core.QgsMapSettings.setLayers)

"Set list of layers for map rendering. The layers must be registered in QgsProject. The layers are stored in the reverse order of how they are rendered (layer with index 0 will be on top)"

My Boundary Layer is index 0 while Slope layer is index 1 but this is my output: enter image description here

The tiff layer is on top of the boundary layer.

What is the problem here? I have tried reversing the order of layers by replacing layers with layers[::-1] but to no avail.


EDIT: running print(ms.layerIds()) give me

'0_Boundary_8deaf683_25ea_4413_ba85_9e932b10db32', '1_1_Slope_3b8789a9_8e2c_4d0f_a81f_ce80955bd4ff']

So I do not know why slope layer is on top of boundary.

2
  • Have you tried : layers.reverse() ? Commented Oct 26, 2020 at 15:19
  • Yes, it doesn't work
    – Sean Ang
    Commented Oct 26, 2020 at 15:51

1 Answer 1

1

For standalone application, for some reason I have to add this line of code:

map.setLayers(layers)

And the layers will appear normally.

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.