4

Is there a way to programmatically access a layer's visibility presets defined in the layer tree view widget (methods, properties, etc.)?

To avoid misunderstandings the part I want to access is the one highlighted in blue in the following screen capture (ex. preset "Test-01" ...)

enter image description here

6
  • 1
    The question is not very clear, could you elaborate a bit more on what you intend to do? Perhaps through an example? Commented Jul 8, 2015 at 14:34
  • 1
    I think that the class you are looking for is this one github.com/qgis/QGIS/blob/master/src/app/qgsvisibilitypresets.h but i'm using qgis 2.4 and i think that presets are not in my system to make tests. I think that you can get it wiht iface.layerMenu() Commented Jul 9, 2015 at 7:48
  • That seems to be THE answer Francisco but i don't find any trace of this class in the API documentation and i don't see how i should call it so far ... I'm using QGIS 2.6
    – Snaileater
    Commented Jul 9, 2015 at 9:13
  • Can anybody tell me if the class QgsVisibilityPresets really exists ? i don't clearly understand the online documentation ...
    – Snaileater
    Commented Jul 14, 2015 at 12:43
  • 1
    @snaileater The link provided by Francisco refers to a class in the app folder of the QGIS source code, which is not exposed to Python bindings. Classes in the core or gui folder are offered in PyQGIS, but not QgsVisibilityPresets. Commented Jul 14, 2015 at 14:11

4 Answers 4

2

You can access the visibilityPresetCollection through the project instance:

QgsProject.instance().visibilityPresetCollection()

http://qgis.org/api/classQgsVisibilityPresetCollection.html

2

If you are using QGIS 3.0 freshly released, instead of

QgsProject.instance().visibilityPresetCollection()

you now have to use the following:

QgsProject.instance().mapThemeCollection()

as stated in QGIS 3.0 API Backwards Incompatible Changes

Then, you can get themes names with:

QgsProject.instance().mapThemeCollection().mapThemes()
1
def activate_visibility_preset(preset_name, *, project=None, coll=None):
  """Activates a visibility preset by its name.
  Return a boolean indicating success."""
  # https://github.com/qgis/QGIS/blob/f044c95fd8927d86967ce8af3930bdc7523095fa/src/app/qgsmapthemes.cpp#L138
  if project is None:
    project = qgis.core.QgsProject.instance()
  if coll is None:
    coll = project.mapThemeCollection()
  if not coll.hasMapTheme(preset_name):
    return False
  root = project.layerTreeRoot()
  model = qgis.utils.iface.layerTreeView().model()
  coll.applyTheme(preset_name, root, model)
  return True

def active_visibility_preset(*, project=None, coll=None):
  """Return the name of the active visibility preset or
  None if no active visibility preset."""
  # https://github.com/qgis/QGIS/blob/f044c95fd8927d86967ce8af3930bdc7523095fa/src/app/qgsmapthemes.cpp#L210
  if project is None:
    project = qgis.core.QgsProject.instance()
  if coll is None:
    coll = project.mapThemeCollection()
  root = project.layerTreeRoot()
  model = qgis.utils.iface.layerTreeView().model()
  curr_mapthemecollection = coll.createThemeFromCurrentState(root, model)
  for preset_name in visibility_presets(project=project, coll=coll):
    checking_preset = coll.mapThemeState(preset_name)
    if checking_preset == curr_mapthemecollection:
      return preset_name

def visibility_presets(*, project=None, coll=None):
  """Return the names of the visibility presets in a list."""
  # https://github.com/qgis/QGIS/blob/f044c95fd8927d86967ce8af3930bdc7523095fa/src/app/qgsmapthemes.cpp#L149
  if project is None:
    project = qgis.core.QgsProject.instance()
  if coll is None:
    coll = project.mapThemeCollection()
  preset_names = coll.mapThemes()
  return preset_names

Usage:

>>> visibility_presets()
['Test-01']
>>> activate_visibility_preset('Test-01')
True
>>> active_visibility_preset()
'Test-01'

Tested on QGIS 3.10.14

Note that you might want to refresh the canvas after changing visibility preset:

qgis.utils.iface.mapCanvas().refreshAllLayers()

Code on GitHub Gist (if you upvote here I would appreciate a star there too)

0

If you have your layer for example as:

layer = iface.activeLayer()

You should get legend:

legend = iface.legendInterface()

Then you can check layers visibility (it returns bool):

legend.isLayerVisible(layer)

Or toggle visibility:

# off
legend.setLayerVisible(layer, False)
# on
legend.setLayerVisible(layer, True)
3
  • yeah thanks i knew these one but u describe a per layer access, my question is about the whole visibility preset (which is a set of "checked" layers) ... how can we access the members of the set, the name of the set, how can we activate a set and/or switch to another ? ...
    – Snaileater
    Commented Jul 8, 2015 at 9:33
  • To be more precise (maybe...) is there a Qgis Class related to these layers visibility presets (i hope i use the right english name, sorry...) ?
    – Snaileater
    Commented Jul 8, 2015 at 9:42
  • If you want to get set of visible layers you have to use for loop on all layers and add them to list or something like that. There isn't any class related to all visible or invisible layers. Maybe layers group, but it isn't related with visibility.
    – dmh126
    Commented Jul 8, 2015 at 9:47

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.