6

I'm trying to update an old plugin to QGIS3 where we use default svg files (in the plugin folder) as markers. It is important that it is the plugin folder since I just to have the entire plugin in one location.

In QGIS2.18 I could specify the path to the svg marker as: :/PLUGIN_NAME/IMAGE_FOLDER/FILENAME.svg

Update: I use an .sld file to specify the .svg path (and other attributes like name etc.) The <se:OnlineResource xlink:type="simple" xlink:href=":/PLUGIN_NAME/IMAGE_FOLDER/FILENAME.svg"/>

When I try it now in QGIS3 I just gets ? instead of the svg symbol, unless I use absolute paths to the plugin and the image folder :(

Update: I tried to add %AppData%/QGIS/QGIS3/profiles/default/python/plugins in front of PLUGIN_NAME, hence without success.

The .qgs file is used in multiple computers, so I want to specify a relative path in the .sld files to the svg file.

Any suggestions how to write it in QGIS3?

2
  • If, in your plugin main.py, the plugin directory has already been defined as self.plugin_dir = os.path.dirname(__file__), could you try using <se:OnlineResource xlink:type="simple" xlink:href=self.plugin_dir + "/IMAGE_FOLDER/FILENAME.svg"/
    – Joseph
    May 3, 2018 at 13:19
  • The problem is that the <se:OnlineResource.... is in the .sld file and not in main.py (self.plugin_dir isn't available). If I look at the path in QGIS it gives me self.plugin_dir/PLUGIN_NAME/IMAGE_FOLDER/FILENAME.svg with that suggestion.
    – axel_ande
    May 3, 2018 at 13:25

4 Answers 4

5
+50

In QGIS2.18 I could specify the path to the svg marker as: :/PLUGIN_NAME/IMAGE_FOLDER/FILENAME.svg

Paths that start with :/ (and qrc:///) are paths to Qt resources. I assume there is a .qrc file which has been compiled/packaged to a resources.py file. The file from QGIS 2 is not compatible with QGIS 3 and you need to recreate the file to be able to continue to use resources (and therefore also paths that start with :/)

Alternatively you can also specify the full path to the svg file (as you post yourself as an answer).

This can also be automated, the following snippet can be used to determine the plugin path:

import os 
plugin_path = os.path.dirname(os.path.realpath(__file__)) # Potentially fix subdirectories

Then check if this path is already configured and add it if missing

svg_paths = QgsSettings().value('svg/searchPathsForSVG')
if plugin_path not in svg_paths:
    QgsSettings().setValue('svg/searchPathsForSVG', svg_paths + [plugin_path])
1
  • Happy if it helps you! May 16, 2018 at 15:38
5

When you use relative path in SLD file, that path is relative to the current working directory (CWD), not relative to SLD file. If you change CWD into your plugin folder, relative path in SLD file works.

Sample plugin folder structure:

enter image description here

SLD File:

<se:OnlineResource xlink:href="./SVG/FILENAME.SVG" xlink:type="simple"/>

In your plugin file plugin_main.py, add below codes to related lines:

import os
.
os.chdir(os.path.dirname(__file__))
.
layer.loadSldStyle("./Styles.sld")
layer.triggerRepaint()

But If you change CWD into another folder later, you get '?' again.

In my QGIS Python console, os.getcwd() returns 'C:\\OSGEO4~1\\bin' and in this case QGIS searchs a file with relative path within that folder.

2
  • Well, this solves the problem when importing the data, hence when another person opens the .qgs the svg marker will show '?' again (the person can of course reload the layer and get it working, but it is not the solution I was looking for) :( However creating a SVG folder in OSGEO\bin folder might be a way forward, however it would be preferable to just have one folder to work with (the plugin folder).
    – axel_ande
    May 9, 2018 at 6:40
  • You're right. The solution I've found so far is to change cwd into my plugin folder. I hope there is a better solution. The fact is that relative path is relative to the current working directory. May 9, 2018 at 10:03
5

Well the solution was to add the folder to the SVG paths

Option to add the svg folder in QGIS

And then use .qml files to store the layer in instead of .sld files and in the .qml file specify the path relative to plugin_folder.

prop v="SVG_folder/SVG_name.svg" k="name"/>

I tried to make it relative to ..QGIS3\profiles\default/svg/ which is added by default, with ../python/plugins/plugin_name/image_folder/svg_name.svg in the .qml file. Which worked locally, hence in the .qgs was the absolute path stored..

4

Assuming you have IMAGE_FOLDER in your working directory you can do something like this".IMAGE_FOLDER/FILENAME.svg" to specify relative path in python3 or if its present one directory above your working directory you can do "..IMAGE_FOLDER/FILENAME.svg".

1
  • I'm sorry, but I think my own solution is better, as I wrote when I used the default\SVG folder and then .. and the path to my plugin. Which worked but the path was stored as an absolute path in the .qgs file.
    – axel_ande
    May 13, 2018 at 15:11

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.