1

I have a script that iterates through layer subgroups in QGIS 3.6, opens a layout with the with the same name as the subgroup and exports a PDF. What I am struggling with is to close the active layout window after the export. Any ideas or other ways of doing such task?

from qgis.core import QgsLayerTreeGroup, QgsLayerTreeLayer
import os,sys

root = QgsProject.instance().layerTreeRoot()
project = QgsProject.instance()
projectLayoutManager = project.layoutManager()
for child in root.children():
    if isinstance(child, QgsLayerTreeGroup):
        #print ("- group: " + child.name())
        for subChild in child.children():
            if isinstance (subChild, QgsLayerTreeGroup):
                print ("- group: " + child.name() + "-subgroup: " + subChild.name())
                #turn on subgroup
                child.setItemVisibilityChecked(True)
                subChild.setItemVisibilityChecked(True)
                #open layout
                l_out = QgsProject.instance().layoutManager().layoutByName(subChild.name())
                iface.openLayoutDesigner(layout=l_out)
                mapName= (subChild.name()+".pdf")
                print (mapName)
                base_path = (r"F:\Documents\PDF")
                print (base_path)
                pdf_path = os.path.join(base_path,mapName)
                print (pdf_path)
                #export layout
                exporter = QgsLayoutExporter(l_out)
                exporter.exportToPdf(pdf_path, QgsLayoutExporter.PdfExportSettings())
                #close Layout
                ???

                #turn off layer
                subChild.setItemVisibilityChecked(False)
  • Why do you open the designer in the first place? I think your script will work fine without this step – ndawson Oct 24 '19 at 7:14
  • You are actually correct, Sir. Thank you – Jan Nov 4 '19 at 10:43
1

You can use the QgsLayoutManager.removeLayout() method to remove layouts:

projectLayoutManager.removeLayout(l_out )
| improve this answer | |
  • Thanks @Joseph. This will do the job. However, using this method the layout is deleted from the project entirely, not just closed. – Jan Oct 23 '19 at 22:08
0

If you have only one layout open:

designer = iface.openLayoutDesigners()[0]
designer.close()

To close a specific layout using its name:

designers = [d for d in iface.openLayoutDesigners() if d.layout().name() == 'Test_Layout']
if designers:
    designers[0].close()

Or close all open layouts:

for d in iface.openLayoutDesigners():
    d.close()
| improve this answer | |
  • This works just fine. Thank you, It appears the layouts do not have to be open at all. – Jan Nov 4 '19 at 10:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.