PyQGIS – Fixing ‘QgsMapCanvas has no attribute setLayers’ Error in QGIS

pyqgispyqt4pythonqgis

I would like to construct a GUI using PyQt4 and qgis outside of the main QGIS application. I found this tutorial which provides some indications on how to do this. I am looking to build something similar.

I was able to open up the MapCanvas object as shown in the PyQGIS cookbook using the following script. I also kept the parts where they were adding buttons for zooming, panning, etc

from qgis.gui import *
from qgis.core import *
from qgis.PyQt.QtGui import QAction
from qgis.PyQt.QtCore import SIGNAL, Qt
from qgis.PyQt.QtWidgets import QMainWindow

class MyWnd(QMainWindow):
    def __init__(self, layer):
        QMainWindow.__init__(self)

        self.canvas = QgsMapCanvas()
        self.canvas.setCanvasColor(Qt.white)

        self.canvas.setExtent(layer.extent())
        #self.canvas.setLayers([layer])

        self.setCentralWidget(self.canvas)

        self.actionZoomIn = QAction("Zoom in", self)
        self.actionZoomOut = QAction("Zoom out", self)
        self.actionPan = QAction("Pan", self)

        self.actionZoomIn.setCheckable(True)
        self.actionZoomOut.setCheckable(True)
        self.actionPan.setCheckable(True)

        self.actionZoomIn.triggered.connect(self.zoomIn)
        self.actionZoomOut.triggered.connect(self.zoomOut)
        self.actionPan.triggered.connect(self.pan)

        self.toolbar = self.addToolBar("Canvas actions")
        self.toolbar.addAction(self.actionZoomIn)
        self.toolbar.addAction(self.actionZoomOut)
        self.toolbar.addAction(self.actionPan)

        # create the map toolsq
        self.toolPan = QgsMapToolPan(self.canvas)
        self.toolPan.setAction(self.actionPan)
        self.toolZoomIn = QgsMapToolZoom(self.canvas, False) # false = in
        self.toolZoomIn.setAction(self.actionZoomIn)
        self.toolZoomOut = QgsMapToolZoom(self.canvas, True) # true = out
        self.toolZoomOut.setAction(self.actionZoomOut)

        self.pan()

    def zoomIn(self):
        self.canvas.setMapTool(self.toolZoomIn)

    def zoomOut(self):
        self.canvas.setMapTool(self.toolZoomOut)

    def pan(self):
        self.canvas.setMapTool(self.toolPan)

QgsApplication.setPrefixPath(r"C:\Program Files\QGIS 2.18", True)
qgs = QgsApplication([], True)
qgs.initQgis()
layer = QgsVectorLayer(r'path\to\layer\layername', 'layername')

w = MyWnd(layer)
w.show()

qgs.exec_()
qgs.exitQgis()

When I run this I get the MapCanvas in a GUI type environment with no issues. However if I uncomment line 15 self.canvas.setLayers([layer]) I get an error message:

>>> execfile('test.py')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "test.py", line 60, in <module>
    w = MyWnd(layer)
  File "test.py", line 15, in __init__
    self.canvas.setLayers([layer])
AttributeError: 'QgsMapCanvas' object has no attribute 'setLayers'

Why does this occur?

How can I set layers to the MapCanvas outside of the qgis application?


Following an answer below I have modified line 15 to self.canvas.setLayerSet([QgsMapCanvasLayer(layer)]) however what I am getting now is a blank map canvas with nothing on it.

Why is this occuring?

Best Answer

The reason is, you are trying to use QGIS 3 API on QGIS 2.

Here is the API for QGIS 2:

https://qgis.org/api/2.18/classQgsMapCanvas.html

Here is the API for QGIS 3:

https://qgis.org/api/classQgsMapCanvas.html

There are 2 solutions to this problem:

  • Use mapCanvas.setLayerSet
  • Work with QGIS 3