I have a Print Layout, with a layer, styled with a color ramp. I create it all with PyQGIS.
How do I, again from PyQGIS, access these two settings Width and Height??
I finally did it, thanks to a post on StackOverflow:
for tree_layer in legend.model().rootGroup().children(): # access the legend's nodes
if tree_layer.name() == layer_name: # confirm you have the correct child node
# tree_layer.layerLegendNodes() = [QgsSimpleLegendNode, QgsColorRampLegendNode] # since mine is a raster layer - double-check your own index
QgsMapLayerLegendUtils.setLegendNodeSymbolSize(tree_layer, 1, QSizeF(6, 25)) # change ONLY this symbol's size
legend.model().refreshLayerLegend(tree_layer)
Kudos to this post. They made me figure out I had to go via QgsMapLayerLegendUtils
instead of trying to edit the legend node directly.
I had the same trouble and also found a solution with a use of QgsMapLayerLegendUtils
.
Just as an addition to @Noxy answer, there are also things I'd like to note.
In my case there were filtered legend items. I.e. there is a layer called "Lines" which has a symbology style with about 50 unique items. I add this layer to legend and then filter it with QgsMapLayerLegendUtils.setLegendNodeOrder()
method which return much less number of items into a legend.
After that I thougt it would be right to loop the remaining symbols and change their sizes. Like this:
legend = QgsLayoutItemLegend(my_layout)
# code of setting my legend item
model = legend.model()
layout_legend_layer = next(filter(lambda i: i.name()=='Красные линии', legend.model().rootGroup().findLayers()))
symbols = model.layerOriginalLegendNodes(layout_legend_layer)
for i, s in enumerate(symbols):
QgsMapLayerLegendUtils.setLegendNodeSymbolSize(layout_legend_layer, i, QSizeF(30, 10))
legend.model().refreshLayerLegend(layout_legend_layer)
legend.updateLegend()
But eventually it did not change sizes of all legend items because setLegendNodeSymbolSize()
is using a list of ALL legend items in layer without taking into account wether it was filtered in layout.
Because of that I decided firstly to collect symbology data from original layer settings and then use these item indexes to change size in layout legend.
layer = QgsProject.instance().mapLayersByName("Lines")[0]
tree_view = iface.layerTreeView()
model = tree_view.layerTreeModel()
layer_tree = model.rootGroup().findLayer(layer.id())
legend_items = model.layerLegendNodes(layer_tree)
# original legend nodes are taken so now we can change their sizes
for i, s in enumerate(legend_items):
QgsMapLayerLegendUtils.setLegendNodeSymbolSize(layout_legend_layer, i, QSizeF(30, 10))
legend.model().refreshLayerLegend(layout_legend_layer)
legend.updateLegend()
After that each size of legend item from my "Lines" layer was changed in layout. This is what I needed to get.
Also there may be another "dirty" solution with use of customProperties()
method of QgsLayerTreeLayer
. When some custom change (size, label) is set on legend item, it goes to customProperties()
list. And you also can see and change them. I my case it would be like
layout_legend_layer.setCustomProperty('legend/symbol-size-0', '30,10')
which should change the size of item after legend update. And the equivalent to previous code will look like
for i, s in enumerate(legend_items):
layout_legend_layer.setCustomProperty('legend/symbol-size-{}'.format(i), '15,15')
legend.model().refreshLayerLegend(layout_legend_layer)
legend.updateLegend()
This is not a good solution but may be helpful in some cases.