1

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??

Item Properties

2 Answers 2

1

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.

1

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.

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.