Opening a vector layer, such as a the countries dataset contained in the Natural Earth geopackage, using the GUI is as simple as double-clicking it in the data source manager or drag-and-dropping it into the map window:

If we want to do the same thing using Python, we need to know the exact source of the layer data. This information can be found in the layer properties. Note how the source contains the path to the geopackage as well as information about the country layer’s layer name:

If you are not using QGIS 3 yet, the above dialog will look different but it contains the same information.

Copy the source information, we’ll need it! Note the forward slashes / in the file path. Even on Windows, you should use forward slashes instead of backward slashes to avoid errors.

Let’s get back to the Python console. As mentioned in the Hello world example, the interactive Python console immediately executes code we input once we press Enter. Since we are planning to write more than one line of code in this example (two actually), it will be convenient to use the built-in code editor instead of the interactive console. It’s basically a text editor that lets you work on multiple lines of code until you’re happy and want to execute it all at once. The Show Editor button in the Python console opens the code editor panel:

Now it’s time to use the source information we copied from the layer properties. We create a variable called uri and store the source information string in it. We choose to call the variable uri – we could call it anything we like. Then we can use the uri as one of three parameters of the iface.addVectorLayer function:

uri = "E:/Geodata/NaturalEarth/vector_v4/natural_earth_vector.gpkg_v4.1.0/packages/natural_earth_vector.gpkg|layername=ne_10m_admin_0_countries"
iface.addVectorLayer(uri, "countries", "ogr")

If you press the Run Script button, the code will be executed and QGIS will load the layer into the current project. Congratulations!

Ok that’s great but what’s this iface thing? iface is an object belonging to QGIS – something that has properties and behaviors we can use to interact with QGIS. iface is a very important object in QGIS because without it, we could not interact with QGIS or any layers loaded in our project. In our code we’ve told the iface object to execute one of the functions which is associated with it – in this case the addVectorLayer function. Different objects are associated with different functions. Just to make life confusing, functions are sometimes called methods. You can find a list of all functions in the official PyQGIS documentation.  You’ll see that addVectorLayer is listed in the documentation as a method belonging to iface with the following description:

addVectorLayer(selfvectorLayerPath: strbaseName: strproviderKey: str) → QgsVectorLayer

This description provides us with some information about the parameters of addVectorLayer:

  1. The first parameter is self. This is a default parameter that is required when writing many Python functions but it does not have to be provided when calling the function. Therefore, we can ignore it and skip ahead to the second parameter:
  2. The description shows that vectorLayerPath should be a string (str). In our example above, we used the string variable uri to provide this input.
  3. The next parameter is a string called baseName. This will be the layer name that is displayed in the layer list and we can pick a value freely.
  4. Finally, the last parameter is a string called providerKey. For most vector data formats (including Geopackage and Shapefile) the provider of choice will be OGR. Other vector provider keys include “postgres”, “delimitedtext”, “gpx”, “spatialite”, and “WFS”. (See also: PyQGIS Developer Cookbook: Loading Layers)

The last part of the description (→ QgsVectorLayer) means that the function returns the created QgsVectorLayer object. Don’t worry about this now, we will get to that in the next examples, promised!

Don’t forget to save! Since scripts are not automatically saved when exiting QGIS, you should make sure to manually save the script using the save button in the editor.

These are the basics of using the code editor to write multiple lines of code that can be executed all at once. You also saw how to interpret a function description from the official PyQGIS documentation.

Next: Viewing vector layer attributes


PyQGIS 101 is a work in progress. I’d appreciate any feedback, particularly from beginners!

Advertisement
30 comments
  1. Kurt said:

    Opening a vector-layer as shown under Windows does not work. You need to replace the backslashes \ with “normal” slashes / in the filepath

    • All Windows screenshots, as well as the code in this post, do already show forward slashes but it might be a good idea to emphasize this fact in the text.

      • Kurt said:

        Strange: When you add a vectorlayer manually via the GUI in windows then QGIS uses the backslash, when you add a layer with python QGIS uses the slash in the Information window

      • Martin said:

        That would be useful, because that’s exactly why I had an error message . Thanks for the tutorial.

      • Done! Thanks for your feedback!

    • Veronika said:

      yes? it`s true

  2. Kurt said:

    BTW whats the usage of the “basename” ?. When I set basename to an empty string, pyqgis loads the layer and the entry in the layers-panel looks exact the same as when I load the vector-layer manually with the qui

    • If no basename is provided, QGIS’ default behavior is to use the file name. The basename parameter can be used to override this default.

      • Kurt said:

        Strange: using QGIS under windows the basename is added to the filename

      • Good catch! I don’t think this used to be the behavior of addVectorLayer in the past or it might be specific to Geopackage layers …

  3. Mohab said:

    Hi anita, as you know QgsMapLayerRegistry is removed form QGIS 3,0 , and from what i understood from section 3.3 on the 2.8 Developer Cook Book —>Map Layer Registry,adding layer to the registry was a different method to add layers instead of iface.addVectorLayer(), was this the case? , is there any other method than iface.addVector , and how to take control of a previously added layer to qgis (a layer within the layers table) to make the necessary modifications on it? …lot of questions …sorry! and thank you in advance…

    • Mohab said:

      hi an again, never mind the first question as it is addMapLayer() function, so after adding it how to take control over…

    • Thank you for letting me know! Should be fixed now.

  4. I don’t think the difference between methods and functions is that confusing. A function is a standalone routine that needs all its data provided from outside, a method principally acts upon the object to which it is attached. The first parameter being self defines it as a method. From a programming POV they are similar enough. A function is an external process that makes a duck quack, whereas a duck has its own method for quacking.

  5. Ed said:

    I love these short tutorials they are easier to comprehend. In this turorial I added a vector but what is the syntax if I want to remove it at the end of the exercise?

  6. Thanks ma’am . This was also straight forward. I’ll tweet you my output once I’m on my PC.

    Feels cool.

  7. Ilvira Khaidarova said:

    First of all, thanks for the great tutorials, they are really usefull.
    The only problem is that the documentation is not very easy to understand. For example, that iface is not mentioned there at all. So, the code we are writing is ‘iface.addVectorLayer(uri, “countries”, “ogr”)’ but the documentation is ‘qgis.gui.QgisInterface’ and ‘addVectorLayer(self, vectorLayerPath: str, baseName: str, providerKey: str)’. There is nothing about iface…

    • Thank you for the feedback Ilvira! I see where the confusion comes from. I’ll try to explain: iface is the predefined name of the instance of QgisInterface that is provided by QGIS by default. It’s best remembered as “iface is a QgisInterface”. Therefore iface has all the properties that are defined for the QgisInterface class. The existence of iface may not be documented in the API documentation but if you open the Python console inside QGIS it reads Use iface to access QGIS API interface or Type help(iface) for more info.

      • Ilvira said:

        I see now :) Thanks!

      • Nathan Perry said:

        Is it accurate to simply say “iface is an object of the class QgisInterface”? And then later, when we use addVectorLayer() to return a QgsVectorLayer object, we’re actually returning an object of the class QgsVectorLayer, but that object isn’t named until the next step (when we assign it to “vlayer”)?

      • Yes, “iface is a QgisInterface” is a shortcut for “iface is an object of the class QgisInterface”.
        When we write vlayer = iface.addVectorLayer(), we store the returned QgsVectorLayer in the vlayer variable. If we don’t store the object in a variable, we cannot access it later on anymore.

  8. badger2100 said:

    Hi- I really like this tutorial. Generally easy to follow, well written. I am a novice to programming/Python/QGIS (I do have ArcGIS experience). I am trying to execute the code above. However, I get an error when the script tries to load the layer as the layer is not valid and cannot be loaded to the map. Thanks for any feedback.

    • badger2100 said:

      Never mind. I figured it out. it wanted a more complete path…Thanks!!

  9. Judith said:

    These are great tutorials – thank you. Whats the easiest way to load multiple files from a directory. I tried
    for file in myfolder:
    iface.addVectorLayer(file, “test”, “ogr”)
    I know that would give each file the same name – just taking it in stages

    I

  10. Gabriel said:

    Hello Anita!
    I’m trying to add one .csv to Qgis and the data have the UTF-8 encoding, how can I define the encoding before add the data to avoid typing issues?
    Thank you!

  11. Dhari said:

    Hello,

    Thanks for the tutorial. Question:

    When executing the line:
    iface.addVectorLayer(uri, “countries”, “ogr”)

    the Layers list window shows the layer’s name as “countres” added to the file name rather than replacing it. That is, it becomes “countries ne_10m_admin_0_countries”

    How can I get it to use the name “countries” that I specified in the command?

    • This is a real head scratcher indeed. So far, this seems to be the best way to get rid of the file name:

      layer = QgsVectorLayer(uri, “countries”, “ogr”)
      QgsProject.instance().addMapLayer(layer)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: