2

I'm looking for a way to edit the title and subtitle from a .qpt layout with the text entered in two QlineEdit.

The code below works if I run it once but nothing happens when I run it twice...

def qpt_loading(self):

    project = QgsProject.instance()

    for filename in glob.glob(self.plugin_path + "/layout_models/*.qpt"):
        with open(os.path.join(os.getcwd(), filename), 'r') as f:
            layout = QgsPrintLayout(project)
            layout.initializeDefaults()
            template_content = f.read()
            doc = QDomDocument()
            doc.setContent(template_content)
            layout.loadFromTemplate(doc, QgsReadWriteContext(), True)
            layout.setName(os.path.basename(filename))

            if layout.name() == "layout_model_A3_landscape_B1":
                ## adding title from lineEdit
                title = QgsLayoutItemLabel(layout)
                layout.addLayoutItem(title)
                title_text = self.dlg.lineEdit_2.text()
                title.setText(title_text)
                title.setFont(QFont("Calibri", 20))
                title.adjustSizeToText()
                title.attemptMove(QgsLayoutPoint(182, 5, QgsUnitTypes.LayoutMillimeters))
                title.adjustSizeToText()
                layout.addItem(title)
                title.setHAlign(Qt.AlignCenter)
                title.setVAlign(Qt.AlignVCenter)

                ## adding subtitle from lineEdit
                subtitle = QgsLayoutItemLabel(layout)
                layout.addLayoutItem(subtitle)
                subtitle_text = self.dlg.lineEdit_3.text()
                subtitle.setText(subtitle_text)
                subtitle.setFont(QFont("Calibri", 16))
                subtitle.adjustSizeToText()
                subtitle.attemptMove(QgsLayoutPoint(182, 18, QgsUnitTypes.LayoutMillimeters))
                subtitle.adjustSizeToText()
                layout.addItem(subtitle)

            project.layoutManager().addLayout(layout)

    updated_layout = QgsProject.instance().layoutManager().layoutByName("layout_model_A3_landscape_B1")

    map_item = layout_modifie.itemById("Map 1")
    # map_item = layout_modifie.referenceMap()

    map_item.zoomToExtent(iface.mapCanvas().extent())
    
    iface.openLayoutDesigner(updated_layout )
1
  • Aside from the idea of using Python to change the layout text elements, have you thought about using QGIS variables (i.e. project variables) as text placeholders? You can easily change variables with Python: QgsExpressionContextUtils.setProjectVariable(QgsProject.instance(), 'myTitle','hello world')
    – christoph
    Commented Oct 21, 2022 at 11:49

1 Answer 1

2

The problem you are observing is most likely due to duplicate layout names. If you are running the script a second time, a layout with given name will already exist (from running it first time, if you don't delete it manually between runs). The statement project.layoutManager().addLayout(layout) does not replace the layout if one exists, it just silently fails.

What you will need to do, is check whether a layout with that name already exists - if yes, remove it before adding the new one:

existing_layout = project.layoutManager().layoutByName(layout.name())
print(existing_layout)
if existing_layout:
    project.layoutManager().removeLayout(existing_layout)
        
result = project.layoutManager().addLayout(layout)
print(result)

In addition, the return type of addLayout will give you a hint on whether addition was successful. You can check in your script whether it returns true or false.

1
  • 1
    Aaah I thought that I could somehow override the existing layout with a new one with project.layoutManager().addLayout(layout). Thanks for your explanation @CodeBard !
    – wanderzen
    Commented Oct 25, 2022 at 7:29

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.