I have a script that was working, where I was able to grab a composer label by its ID and then update its text by doing the following:

labelTitle = myComposition.getComposerItemById('pageTitle')
labelTitle.setText('New Title')

But after updating to the latest version of QGIS, it looks like labelTitle is coming back as a QgsComposerItem type instead of QgsComposerLabel, so it is throwing the error 'QgsComposerItem' object has no attribute 'setText'

Is there a way to cast it as a label, or am I missing something? Or is there an entirely better way to accomplish this?

  • Do you generate your title from a field in the map or are you using the atlas function?. If using a field in a vector file you could do something like This is the [%"field_name"%] where field name would hold your string
    – LaughU
    Commented May 22, 2017 at 6:01
  • @LaughU Yeah I actually just figured this out and was about to update my post. I'm generating it from a field and was doing it programmatically in the script so that I could change the size based on the length of the title, but I ended up just using a conditional in the label expression. I'm still curious how to target a composer label with Python though!
    – Alex
    Commented May 22, 2017 at 6:17
  • could you add which QGIS version you used and which you are using now?
    – LaughU
    Commented May 22, 2017 at 12:28
  • @LaughU I'm on 2.18.7 running on a Mac, previously I want to say it was 2.18.0
    – Alex
    Commented May 22, 2017 at 16:29

3 Answers 3


Another workaround suggested by Nyall Dawson (cast) :

from qgis.core import QgsProject, QgsLayoutItemPicture
import sip
myLayout = QgsProject.instance().layoutManager().layoutByName('test')
myLayoutPicture = sip.cast(myLayout.itemById("picture"), QgsLayoutItemPicture)
myLayoutPicture.setPicturePath("path to an image")

same problem for me, solved with this:

    item = myComposition.getComposerItemById("id_field")
    item = self.bugWAGetComposerLabel(item)
    item.setText("my value")

def bugWAGetComposerLabel(self, item):
    if not item.__class__ == QgsComposerLabel:
        if item.type() == QgsComposerItem.ComposerLabel:
            item.__class__ = QgsComposerLabel
    return item
  • Same problem here (QGIS 2.99), but with this code I get an error : 'QgsComposerLabel' object has no attribute 'setText'
    – sigeal
    Commented Nov 28, 2017 at 9:48

Here is the workaround I found with the help of QGIS Developer list :

def getCompositionItem(composition, itemId, itemClass):
    item = None
    for item in composition.items():
        if isinstance(item, itemClass):
            if item.id() == itemId:
                return item

Using this custom function instead of getComposerItemById I can get composition items with their actual subclass.


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.