I'm struggling to understand how to manage print layouts using python for QGIS. For example, I am starting with Zero exisiting print layouts in my layout manager. I create a new print layout and add a label to it with this code:
project = QgsProject.instance()
manager = project.layoutManager()
layout = QgsPrintLayout(project)
layout.initializeDefaults()
layoutName = "PrintLayout"
layout.setName(layoutName)
manager.addLayout(layout)
layout.setName(layoutName)
manager.addLayout(layout)
title = QgsLayoutItemLabel(layout)
title.setText("Title Here")
title.setFont(QFont("Arial", 28))
title.adjustSizeToText()
layout.addLayoutItem(title)
title.attemptMove(QgsLayoutPoint(10, 4, QgsUnitTypes.LayoutMillimeters))
This is simple enough, it creates a new print layout called "PrintLayout" and it looks like this:
But if I run this code another time, I start getting problems. If I run exactly the same code, except I change the following line:
title.setText("Title There")
I get the following result. As you can see, "Title There" and "Title Here" are now overlaid on top of each other. This isn't good.
So I started thinking if an existing print layout exists with the same name, maybe I can delete that layout and create a new one. So I try the following code:
project = QgsProject.instance()
manager = project.layoutManager()
layout = QgsPrintLayout(project)
layout.initializeDefaults()
layoutName = "PrintLayout"
layout.setName(layoutName)
manager.addLayout(layout)
layouts_list = manager.printLayouts()
for layout in layouts_list:
print(layout.name())
for layout in layouts_list:
if layout.name() == layoutName:
layouts_list.remove(layout)
for layout in layouts_list:
print(layout.name())
title = QgsLayoutItemLabel(layout)
title.setText("Title There")
title.setFont(QFont("Arial", 28))
title.adjustSizeToText()
layout.addLayoutItem(title)
title.attemptMove(QgsLayoutPoint(10, 4, QgsUnitTypes.LayoutMillimeters))
Notice, I created a variable "layouts_list" which stores my layouts and for loop to check the names of existing layouts, if the name equals the new layout I want to create, I remove before creating a new one. Also, I print the layout names from the layout manager before and after checking the layout names.
However, it seems the .remove() method doesn't actually remove a layout from the layout manager.
J.Monticolo suggested I try the .removeLayout() method. So I modified my for loop like this:
for layout in layouts_list:
if layout.name() == layoutName:
manager.removeLayout(layout)
This does actually remove the layout from the layout manager. But I'm met with this error:
This makes sense. I did delete the layout. But a new layout is not created. They should be as my remaining code makes a new layout and adds a title to it.
Why does this error message stop the code, before creating a new layout?
Here is the final code all together:
project = QgsProject.instance()
manager = project.layoutManager()
layout = QgsPrintLayout(project)
layout.initializeDefaults()
layoutName = "PrintLayout"
layout.setName(layoutName)
manager.addLayout(layout)
layouts_list = manager.printLayouts()
for layout in layouts_list:
if layout.name() == layoutName:
manager.removeLayout(layout)
layout.setName(layoutName)
manager.addLayout(layout)
title = QgsLayoutItemLabel(layout)
title.setText("Title There")
title.setFont(QFont("Arial", 28))
title.adjustSizeToText()
layout.addLayoutItem(title)
title.attemptMove(QgsLayoutPoint(10, 4, QgsUnitTypes.LayoutMillimeters))
QgsLayoutManager.removeLayout
method ?