I have a QGIS project which contains a composer. Of course if I go into the GUI I can export it as a pdf etc. For my make script though I want to have this done via a python script. From reading online here is my attempt:

#!/usr/bin/env python

import sys
from qgis.gui import QgsMapCanvas, QgsLayerTreeMapCanvasBridge
from PyQt4.QtCore import QFileInfo
from PyQt4.QtXml import QDomDocument
from qgis.core import *

qgs = QgsApplication(sys.argv, True) 
QgsApplication.setPrefixPath("/usr", True) 


def make_pdf():
  canvas = QgsMapCanvas()
  bridge = QgsLayerTreeMapCanvasBridge(
      QgsProject.instance().layerTreeRoot(), canvas)

  composition = QgsComposition(canvas.mapSettings())
  map_item = composition.getComposerItemById('board36x48')


This fails, specifically:

QGraphicsScene::addItem: item has already been added to this scene
Traceback (most recent call last):
  File "./assets/generate_board", line 30, in <module>
  File "./assets/generate_board", line 24, in make_pdf
AttributeError: 'NoneType' object has no attribute 'setMapCanvas'

I based this off of Save Print/Map QGIS composer view as PNG/PDF using Python (without changing anything in visible layout)? but modified it to simplify as much as possible. It seems like I broke something in the process... I don't have this template file. I simple have a board.qgs project file with a composer board36x48. Any ideas?

  • Try replacing qgs = QgsApplication(sys.argv, True) with app = QtGui.QApplication(sys.argv, True) and qgs.initQgis() with QgsApplication.initQgis()?
    – Joseph
    Commented May 19, 2017 at 9:43
  • You might find some useful piece of code here in the Maps_printer plugin : github.com/DelazJ/MapsPrinter/wiki . Look for def saveFile(self):, def printToRaster(self, cView, folder, name, ext):, def exportCompo(self, cView, folder, title, extension):
    – gisnside
    Commented Sep 5, 2017 at 13:21
  • did you get it work ? Commented Oct 25, 2017 at 14:25

1 Answer 1


You are trying to create the QgsComposerMap item from your complete composer name !

map_item = composition.getComposerItemById('board36x48')

use instead the ID of the map component in your composer (map; map0; map1...). You defined it when you create your composer.

According other piece of code are ok, you should get it work.

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.