1

In the Qgs Project is a csv table file with two fields and two features/Objects.

The script I'm writing is supposed to replace two textlabels in my only open layout with the attributes in the second field of the table.

My script has the following procedure:

1) take the table from the project and store it in a variable

2) take the text labels from the layout and store it in a variable

3) compare the text labels with the attributes from the first field and if they are equal overwrite the text label with the content from the second field.

My script doesn't give me an error message but it is not doing anything. apparently I missed something but I don't see what it is. Hoping for help.

Here is the code:

    def getTable(self):
    """gets table from the QGIS Project"""
    layer = None
    for lyr in QgsProject.instance().mapLayers().values():
        if lyr.name() == "table":
            layer = lyr
            break
    return layer

def setVariable(self):
    """adds the table to a variable called self.inTable"""
    self.inTable = self.getTable()

def changeLabel(self):

    """saves the Layout label texts in a variable"""
    labels = None
    for l in QgsProject.instance().layoutManager().layouts()[0].items():
        if isinstance(l,QgsLayoutItemLabel):
            labels = l

    """gets the features of the table"""
    features = self.inTable.getFeatures()

    """compares the list of labels with the attributes in the first 
    column of the features and replaces the label with the attribute
    from the second column"""
    for label in labels:
        for feat in features:
            if label == feat.attributes()[0]:
                labels[label] = feat.attributes()[1]
    return labels

def run(self):
    """Run method that performs all the real work"""
    self.dlg.show()
    # Run the dialog event loop
    result = self.dlg.exec_()
    # See if OK was pressed
    if result:
        self.setVariable()
        self.changeLabel()

I guess there is something wrong in the changeLabel function but I don't see what it is. Or I completely forgot somethin.

1 Answer 1

1

There are a few problems with your code.

Firstly, when you iterate over the items in your layout, you are trying to assign multiple label objects to a single variable. That 'labels' variable will only return one label object. In order to collect all the label objects so you can iterate over them again, you need to store them in a list instead.

Secondly, instead of evaluating the label's current text, you are evaluating the label object itself against your table attribute value. This will always evaluate to False!

Thirdly, you need to call the setText() method on the labels and pass the second attribute value cast to a string.

Below is a minimal example which should accomplish what you are trying to do. In case you have more than one layout in the project's layout manager, I suggest getting the layout explicitly using the layoutByName() method. There is also a mapLayersByName() method which simplifies accessing your table layer.

You can test this code in the python console then adapt it for your plugin. Just change the table layer name and layout name to match your own.

#get table by its name
tbl = QgsProject().instance().mapLayersByName('Test_Table')[0]
#get layout by its name
layout = QgsProject().instance().layoutManager().layoutByName('Test')
#get label objects and store them in a list
labels = [i for i in layout.items() if isinstance(i, QgsLayoutItemLabel)]
# store table layer features in a list
feats = [f for f in tbl.getFeatures()]
for l in labels:
    for f in feats:
        #evaluate label text against feature attribute
        if l.text() == f.attributes()[0]:
            #call setText() on label object and pass attribute as a string
            l.setText(str(f.attributes()[1]))

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.