Advertisements

A common topic for automation is exporting print layouts (formerly known as print compositions). This example shows you how to export a print layout to PDF. This code can be easily adapted to export to image or SVG as well.

We already used the QgsProject object in the previous example to add Processing results to our project. Now, we use the QgsProject to access the corresponding QgsLayoutManager which takes care of managing all configured layouts in a project.

If we open a project that has a print layout configured and run the following two lines of code in the Python console:

manager = QgsProject.instance().layoutManager()
print(manager.printLayouts())

we get a list of QgsPrintLayout objects. If the project has just one layout, the list will only contain one item, like this:

[<qgis._core.QgsPrintLayout object at 0x000001D288C020D8>]

Of course, we can also print out the names of the layouts in our project using our favorite loop, the for loop:

for layout in manager.printLayouts():
    print(layout.name())

These names can be used to access specific layouts. So, for example, to get the layout named “my_layout”, we use the layoutByName() function:

layout = manager.layoutByName("my_layout")

So far so good! Now there’s just one issue: layout objects do not have an export function! Instead, the documentation of QgsLayout (which is the base class of QgsPrintLayout*) tells us:

While the raw QGraphicsScene API can be used to render the contents of a QgsLayout to a QPainter, it is recommended to instead use a QgsLayoutExporter to handle rendering layouts instead.

So to export our layout, we need a QgsLayoutExporter. These exporters can export to image, SVG, and PDF. To create an exporter for our layout object, we use:

exporter = QgsLayoutExporter(layout)

Finally, we can export the layout, for example, to PDF:

exporter.exportToPdf("C:/temp/layout.pdf",QgsLayoutExporter.PdfExportSettings())

* Before we wrap up this example, there was this notion of QgsLayout being the base class of QgsPrintLayout or conversely, as stated in the QgsPrintLayout  documentation:

Print layout [is] a QgsLayout subclass for static or atlas-based layouts.

A class is like a “blueprint” for creating objects. The class defines which attributes and functions an object has. In this example, our layout is a QgsPrintLayout object. It therefore has all the functions and attributes defined by the QgsLayout class, as well as the QgsPrintLayout class. This concept is called inheritance and you can read more about it, for example, at python-course.eu.

These are the basics of exporting map layouts to PDF. You also saw an example of inheritance with QgsLayout as the base class and QgsPrintLayout as the subclass.

Next


PyQGIS 101 is a work in progress. I’d appreciate any feedback, particularly from beginners!

Advertisements
6 comments
  1. Alen Mangafić said:

    Nice post!
    The main problem I have in printLayouts, within a plugin of mine, is that the Layout Manager is storing somewhere (literally I can’t find where) a predefined template (I made a QPT template that can be changed by the plugin), which is not updated within the Layout manager after a template change is committed (the QPT is changed and saved). When I change the QPT file, I have to delete the Layout from the Layout Manager and recreate the specific Layout from scratch. Any ideas how to solve this, like refresh for example?
    Best regards,
    Alen

    • That’s a very interesting topic which I haven’t investigated yet. I don’t think there is any built-in functionality to refresh a layout based on a template but to make sure, I’d recommend asking on the mailing list.

  2. Geert Soet said:

    Thank you very much for this tutorial, setting my first baby steps into the Pyqgis world. I have one error though running it on windows, on osx it works like a charm. The code I run:

    layout = manager.layoutByName(“Regio”)
    exporter = QgsLayoutExporter(layout)
    exporter.exportToPdf(“C:/Users/Geert/Desktop”,QgsLayoutExporter.PdfExportSettings())

    The error I get:

    Traceback (most recent call last):
    File “C:\OSGEO4~1\apps\Python37\lib\code.py”, line 90, in runcode
    exec(code, self.locals)
    File “”, line 1, in
    File “”, line 1, in
    NameError: name ‘manager’ is not defined

    My end goal is to run this as an external python script that outputs atlas images based on an external query.

    • Geert Soet said:

      Ah, I forgot the step to store the returned request in the vlayer object. Problem solved, thanks again.

  3. Leni said:

    Hi Anita,
    this is a very good starting point for using Python in QGis for newbies.
    I would appreciate an example for looping through lists.
    As example: I have pleanty of print layouts and I want to export them all in one hand so that I get an image/pdf for every print layout with the given name (of course it can be done with the extension MapsPrinter but that’s not the point in learning python ;-))

    • Hi Leni,
      We’re looping through the list of print layouts using
      for layout in manager.printLayouts():
      but it’s a good idea, so I’ll add a code snippet when I get around to testing it.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: