Since this topic covers a lot of arguments, I will only focus on the SVG symbol layers, hoping that I have understood well what are you looking for (I didn't realize the length of the answer while writing, so I'm sorry for that but I hope it will add more clearness, though).
Context
1) Symbol layer classes
The following symbol layer classes are available for SVG format:
- QgsSvgMarkerSymbolLayerV2, which displays a point geometry using a specified SVG image (it works for point layers);
- QgsSVGFillSymbolLayer, which draws the interior of a polygon geometry using a repeated SVG image (it works for polygon layers).
A common approach for creating a symbol layer is initialising it with a dictionary of properties.
You may initialize a new symbol layer and see its default properties in this way:
symbol_layer = QgsSvgMarkerSymbolLayerV2()
for k,v in symbol_layer.properties().iteritems():
print k, ':', v
You will obtain all the properties that are stored in it:
outline_width : 0.2
outline_color : 0,0,0,255
angle : 0
name : crosses/Star1.svg
scale_method : diameter
color : 0,0,0,255
size_unit : MM
horizontal_anchor_point : 1
size_map_unit_scale : 0,0,0,0,0,0
outline_width_unit : MM
offset : 0,0
offset_map_unit_scale : 0,0,0,0,0,0
outline_width_map_unit_scale : 0,0,0,0,0,0
size : 4
vertical_anchor_point : 1
offset_unit : MM
If you want to edit the properties, you may use methods, which are callable from the help of the class (e.g. run help(QgsSvgMarkerSymbolLayerV2)
in the Python Console). You'll see later an example of how using methods.
For the sake of completeness, you may also initialize a symbol layer with a dictionary of properties (for example, see here), but I sincerely prefer the first approach and I will use it.
2) Creating a renderer
To use the symbol layer once you have created it (and eventually edited), you need to create an appropriate renderer and then assign that renderer to your map layer.
To access the existing renderer of a layer:
renderer = layer.rendererV2()
To get a list of the available renderer types, use:
renderer_types = QgsRendererV2Registry().renderersList()
For your case, we should deal with a Categorized symbol renderer. As I said before, you need to create a renderer and then assign it to the layer:
# define the lookup: value -> (color, label)
landuses = {'Agriculture': ('#d3a151', 'Agriculture'), 'Natural': ('#175dcd', 'Natural'),}
# create a category for each item in landuses
categories = []
for landuse_name, (color, label) in landuses.items():
symbol = QgsSymbolV2.defaultSymbol(layer.geometryType())
symbol.setColor(QColor(color))
category = QgsRendererCategoryV2(landuse_name, symbol, label)
categories.append(category)
# create the renderer and assign it to the layer
expression = 'landuse' # field name
renderer = QgsCategorizedSymbolRendererV2(expression, categories) # categorized symbol renderer
layer.setRendererV2(renderer) # assign the renderer to the layer
3) Changing symbol layer
The several symbols of the Categorized symbol renderer are callable through symbols()
(it returns a list):
for symb in renderer.symbols():
print symb
<qgis._core.QgsMarkerSymbolV2 object at 0x0E1FF760>
<qgis._core.QgsMarkerSymbolV2 object at 0x0E1FF7B0>
If you want to replace a given symbol layer within the symbol
defined before, you only need to know its index and then tell it to the renderer in this way:
renderer.symbols()[0].changeSymbolLayer(0, new_symbol)
where [0]
indicates the first item of the categorized group.
Solution
Finally, let's apply what we just have learned!
Assuming to work on this polygon layer, which stores the land uses we have defined before:
If you want to change the default pattern for the agricultural land uses (they have the position No. 1 in the 'landuse' group) with a specific SVG image, you may run this code (read here for knowing how to add a custom SVG path):
import qgis
from PyQt4.QtCore import *
from PyQt4.QtGui import *
# define the lookup: value : (color, label)
landuses = {'Agriculture': ('#d3a151', 'Agriculture'), 'Natural': ('#175dcd', 'Natural'),}
# create a category for each item in landuses
categories = []
for landuse_name, (color, label) in landuses.items():
symbol = QgsSymbolV2.defaultSymbol(layer.geometryType())
symbol.setColor(QColor(color))
category = QgsRendererCategoryV2(landuse_name, symbol, label)
categories.append(category)
# create the renderer and assign it to the layer
expression = 'landuse' # field name
renderer = QgsCategorizedSymbolRendererV2(expression, categories)
activeComposer = iface.activeComposers()
for item in activeComposer:
if item.composerWindow().windowTitle()=='test':
for i in item.items():
if isinstance(i,QgsComposerLegend):
legend = i
for k in xrange(legend.modelV2().rowCount()):
posteleg=legend.modelV2().index(k, 0)
layer = QgsMapLayerRegistry.instance().mapLayersByName( posteleg.data() )[0]
if k == 0: # k is the position of the layer of interest in Legend (NOT in the Layers Panel)
svg_location = 'C:/path_to_svg/smile.svg'
new_symbol = QgsSVGFillSymbolLayer()
new_symbol.setSvgFilePath(svg_location)
new_symbol.setPatternWidth(7.0)
#... If you want to set additional parameters, type help(QgsSVGFillSymbolLayer) in the Python Console
renderer.symbols()[1].changeSymbolLayer(0, new_symbol)
layer.setRendererV2(renderer)
layer.triggerRepaint()
This will be the result:
The code above is very rough but, since I didn't know if you wanted a specific solution for your example or a more general explanation, I preferred to focus the attention on the available tools instead of refining the code itself (I'm sure you are able to slightly edit it according to your specific needs!).
Best Answer
You can set transprency at two levels, the "Layer Transparency" and/or the "Symbol Layers".
Selecting Style in the Layer Properties you should see Layer Transparency under the Style heading on the right. This affects the layer but does not affect the symbol in the legend. (Long transparency slider and box)
Selecting Style and going to the Symbol Fill properties you should have access to another level of transparency. This will affect layer fill transparency for the selected symbol and will show up in the legend. (Transparency Slider only, assuing Single Symbol mode)