6

How can I refresh the Layers Panel in QGIS through python?

In my code I have loop and within line to update visibility of some layer in the legend:

self.iface.legendInterface().setLayerVisible( layer, True )

At the beginning I thought it should do that that automatically. But it doesn't. Very interesting thing for me is that if I have open Python Console and print something after that line the Layers Panel gets updated. If the Python Console is closed nothing happens.

My intention is to build plugin witch loop through layers in selected group and for every layer turns it on (the rest in group turn off) and export composer. The whole problem is that after switching visibility of layers the Layers Panel won't update automatically and so also the composer is not updated and gets exported without any change in the layers visibility. Just accidentally I have found out that if I open Python Console and with every loop print out something not only Python Console gets updated but for some reason also Layers Panel and so Composer and so the export works as needed. But I feel it would be stupid to say if you want my plugin to work correctly you need to open python console... There must be some trigger or something to force Layers Panel to update. What is it? :)

  • Does it not work if you add a print line after your loop? – Joseph Sep 30 '16 at 9:21
  • @Joseph it works only if the python console is open (or was open - once open it can be closed and the Layers Panel gets still refreshed on print command which I find strange. Anyway I need something to refresh Layers panel in standard way and not that it gets coincidentally refreshed with print into Python Console. – Miro Sep 30 '16 at 9:34
  • 1
    Maybe you can try adding this at the end of your loop: self.iface.legendInterface().refreshLayerSymbology(layer) – Joseph Sep 30 '16 at 9:53
  • 1
    Perhaps what you actually need is to update the composer legend right before exporting the composer. You can iterate composer items and once you get the legend, call its updateLegend() method, like this: from qgis.core import QgsComposerLegend for item in composer.composition().items(): if isinstance(item, QgsComposerLegend): item.updateLegend() break – Germán Carrillo Oct 2 '16 at 22:19
  • 1
    Honestly, it's really difficult to reproduce your problem. I even developed a test plugin from scratch and always got the layer panel updated. The only issue I faced was that the composer legend wasn't refreshed in all PNGs I generated. After using the code above, all the PNGs got the legend refreshed. If you're interested in the code I ended up using, you can find it here. – Germán Carrillo Oct 4 '16 at 1:16
4

This answer might be related to many other problems too. Thanks to the Maps Printer plugin I have figured out how to ensure things are going to be refreshed (processed) as needed:

from PyQt4.QtCore import QCoreApplication

# This line is going to update (process) everything which might wait in cue like refreshing the layers in map in print composer
QCoreApplication.processEvents()

My big thanks to the developer of Maps Printer plugin (Harrissou Sant-anna / CAUE du Maine-et-Loire) who's code contains these lines which helped me to figure this out and Germán Carrillo who pointed me in the right direction.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.