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
    May 19 '17 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
    Sep 5 '17 at 13:21
  • did you get it work ? Oct 25 '17 at 14:25

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, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.