My goal is to make a standalone application using the QGIS library, but for now I'm trying to make everything work in a QGIS plugin.

I need to create a map canvas inside my plugin window. There is some good documentation right here: http://docs.qgis.org/testing/en/docs/pyqgis_developer_cookbook/canvas.html#id2

But I still didn't got it to work. Here's what I did:

1) In QT designer, I created a widget and promoted it like the documentation tells me to do. That looks like this:

enter image description here

I'm not sure if the object Name of this widget matters?

2) Next I wrote some code to import an XML file as a raster image. The XML file points to the Google Sattelite raster image.

    canvas = QgsMapCanvas()


    layer = QgsRasterLayer(r"C:\Users\Kristof\Desktop\google.xml", "Google")

    # add layer to the registry

    # set extent to the extent of our layer

    # set the map canvas layer set

When I execute the code, It does load the raster image but it shows it on the main qgis map, instead of my own little map canvas. My own canvas just stays blank, not even sure if it's "working"

What am I doing wrong?

Here is my complete code:

from PyQt4.QtGui import (QMainWindow, QWidget, QGridLayout, QSizePolicy, QDockWidget, QIcon, QColor, QAbstractItemView, QToolBar, QToolButton, QCheckBox, QLabel, QDoubleSpinBox, QAction) from PyQt4.QtCore import (Qt, QRect, QTimer, pyqtSlot, pyqtSignal, QSettings, QCoreApplication)

import qgis

from qgis.gui import (QgsRubberBand, QgsLayerTreeMapCanvasBridge, QgsLayerTreeView,
                  QgsMapCanvas, QgsMapToolPan,
                  QgsVertexMarker, QgsMessageBar, QgsMapCanvasLayer)
from qgis.core import (QGis, QgsMapLayerRegistry, QgsProject, QgsLayerTreeModel, QgsLayerTreeGroup,
                   QgsVectorLayer, QgsGeometry, QgsRectangle, QgsPoint)

import locale
import os
import json

class Kristof3: """QGIS Plugin Implementation."""

# initiatie fictieve tussenafstand in meters
global Gtussenafstand
Gtussenafstand = int(3)

def __init__(self, iface):

    :param iface: An interface instance that will be passed to this class
        which provides the hook by which you can manipulate the QGIS
        application at run time.
    :type iface: QgsInterface
    # Save reference to the QGIS interface
    self.iface = iface
    # initialize plugin directory
    self.plugin_dir = os.path.dirname(__file__)
    # initialize locale
    locale = QSettings().value('locale/userLocale')[0:2]
    locale_path = os.path.join(

    if os.path.exists(locale_path):
        self.translator = QTranslator()

        if qVersion() > '4.3.3':

    # Create the dialog (after translation) and keep reference
    self.dlg = Kristof3Dialog()

    # Declare instance attributes
    self.actions = []
    self.menu = self.tr(u'&Kristof3')
    # TODO: We are going to let the user set this up in a future iteration
    self.toolbar = self.iface.addToolBar(u'Kristof3')


# noinspection PyMethodMayBeStatic
def tr(self, message):
    """Get the translation for a string using Qt translation API.

    We implement this ourselves since we do not inherit QObject.

    :param message: String for translation.
    :type message: str, QString

    :returns: Translated version of message.
    :rtype: QString
    # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
    return QCoreApplication.translate('Kristof3', message)

def add_action(
    """Add a toolbar icon to the toolbar.

    :param icon_path: Path to the icon for this action. Can be a resource
        path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
    :type icon_path: str

    :param text: Text that should be shown in menu items for this action.
    :type text: str

    :param callback: Function to be called when the action is triggered.
    :type callback: function

    :param enabled_flag: A flag indicating if the action should be enabled
        by default. Defaults to True.
    :type enabled_flag: bool

    :param add_to_menu: Flag indicating whether the action should also
        be added to the menu. Defaults to True.
    :type add_to_menu: bool

    :param add_to_toolbar: Flag indicating whether the action should also
        be added to the toolbar. Defaults to True.
    :type add_to_toolbar: bool

    :param status_tip: Optional text to show in a popup when mouse pointer
        hovers over the action.
    :type status_tip: str

    :param parent: Parent widget for the new action. Defaults None.
    :type parent: QWidget

    :param whats_this: Optional text to show in the status bar when the
        mouse pointer hovers over the action.

    :returns: The action that was created. Note that the action is also
        added to self.actions list.
    :rtype: QAction

    icon = QIcon(icon_path)
    action = QAction(icon, text, parent)

    if status_tip is not None:

    if whats_this is not None:

    if add_to_toolbar:

    if add_to_menu:


    return action

def initGui(self):
    """Create the menu entries and toolbar icons inside the QGIS GUI."""

    icon_path = ':/plugins/Kristof3/icon.png'

def unload(self):
    """Removes the plugin menu item and icon from QGIS GUI."""
    for action in self.actions:
    # remove the toolbar
    del self.toolbar

def test(self):

    canvas = QgsMapCanvas()


    layer = QgsRasterLayer(r"C:\Users\Krist\Desktop\google.xml", "Google")

    #layer = QgsVectorLayer(r"C:\Users\krist\Desktop\vector.shp", "layer_name_you_like", "ogr")

    # add layer to the registry
    QgsMapLayerRegistry.instance().addMapLayer(layer, True)

    # set extent to the extent of our layer

    # set the map canvas layer set



def run(self):
    """Run method that performs all the real work"""
    # show the dialog
    # Run the dialog event loop
    result = self.dlg.exec_()
    # See if OK was pressed
    if result:
        # Do something useful here - delete the line containing pass and
        # substitute with your code.

closed as too broad by PolyGeo May 21 '18 at 21:34

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.


I'm not pretty sure this answer will fit with your final goal but to make it works in your QGIS plugin, you need to find your plugin canvas in the QgsInterface when it's load with something like this if your are out of your plugin instance:


You have to adapt the argument to fit to your configuration (change 'Widget' with the type of Widget you use (e.g. DockWidget) and replace the string name.

This would store your canvas object in the canvas variable and allow you to perform your tasks on this specific object.

When you do

canvas = QgsMapCanvas()

I think you just create a new instance of a QgsMapCanvas Object.

Or as you work already in an instance of your plugin, you can get it with something like:

canvas = self.dlg.ObjectNameOfYourMapCanvasInQT()

Another thing is, if you don't want your layer be add in the main canvas, that you need to add False in the following line:


For example this snippet works for me in the python console:

from qgis.gui import *

canvas = QgsMapCanvas()
layer = QgsRasterLayer(r'C:/Users/ylecomte/Desktop/Tmp/IMG/apercu.png', 'layer')



Change the promote class name and be sure you do not have a conflict with any of the qgis classes. The methods on self are from the qgis canvas, not from the plugin.


In your code you constructed your canvas with your plugin as its parent.

    self.canvas = QgsMapCanvas(self)

I do not think that you are supposed to do that. If you don't give a specific parent parameter QgsMapCanvas' parent is null. But in your case QgsMapCanvas has a your Kristof3 object which is not a widget as parent. In QGIS, parent of the mapCanvas' parent is the central widget. May be you can try

    self.canvas = QgsMapCanvas()
  • I Still didn't fix it.. I also tried making a QGraphicsView in stead of a QWidget, but still not map .. – Kristof de Werdt May 31 '16 at 14:52
  • I'm sorry for the confusion. The use of all the "self' was done later, for testing reasons. I edited the code (removed all the 'self'), this is what is was like in the beginning – Kristof de Werdt Jun 1 '16 at 8:10

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