4

I am writing a plugin using Python and currently using methods that set the label similar to those seen under Layer Properties. Some of the features under the new labelling engine available on the Toolbar would be useful, such as (not) "Label every part of a multi-part feature" and avoiding label collisions. Also the look of the labels generated using the latter method are usually better. Is there any way of setting these programatically in Python?

I understand the Toolbar labelling system will supersede the version under Layer Properties, so if they are not available in the API, will they be in the future?

1
  • Best to make a specific feature request on the tracker. Commented Sep 5, 2012 at 20:54

1 Answer 1

5

You can publicly access many of the 'advanced' (or PAL) labeling engine functions via several classes, though the settings classes do not have sip (Python) bindings yet:

QgsLabelingEngineInterface

This is the main PAL engine interface that is really part of QgsMapRenderer, so you will want to gain access to it with the following in QGIS's Python console:

iface = qgis.utils.iface
mc = iface.mapCanvas()
mr = mc.mapRenderer()
le = mr.labelingEngine()

You will generally not need to work with the engine via Python. One aspect of accessing the engine directly that might be useful: gain direct access to the labels that have already be rendered. This is how the PAL label manipulation tools in the toolbar work (from master branch: Pin/Unpin, Show/Hide, Move, Rotate, Change):

le.labelsAtPosition(QgsPoint)  # returns a label of class QgsLabelPosition
le.labelsWithinRect(QgsRectangle)  # returns list of labels
# e.g. le.labelsWithinRect(mc.extent()) would return all visible labels drawn to canvas

see also: QgsLabelPosition

QgsPalLabeling

This is where you can set temporary engine-specific options like search method, show candidates, etc. as you can in the Engine settings dialog. There is currently no Python binding for this class.

Having a sip file created (Python binding) for this class, and the following, is the feature request you will want to submit, as per @lynxlynxlynx's suggestion.

QgsPalLayerSettings

This is where you can access, manipulate and write PAL settings for a given vector layer (which I think is what you are looking to do). Unfortunately, there is currently no Python binding for this class, which is defined in the QgsPalLabeling file, and I don't think there is a means of accessing it via another bound class.

Once a binding is in place, you will probably be able to access PAL layer settings like:

palyr = QgsPalLayerSettings()
palyr.readFromLayer(iface.activeLayer())  # assuming active layer is of vector type
if not pallyr.labelPerPart:  # access "Label every part of a multi-part feature"
    pallyr.labelPerPart = True
palyr.writeToLayer(iface.activeLayer())
# you have just adjusted settings like via the GUI, now redraw the canvas
mc.refresh()

Check the the QgsPalLabeling class's header and source file comments for info on defaults for QgsPalLayerSettings options.

5
  • Thanks for you detailed reply. QgsPalLayerSettings is listed in the API Documentation: QgsPalLayerSettings. Does this mean there is a Python binding in place or do I need to request the specific features I want? Commented Sep 7, 2012 at 12:38
  • I want to programatically set labels and other attributes from the Python code so the user gets a nice looking layer without needing to change the layer properties themselves. Will the PAL labelling engine eventually be removed from the toolbar and go into Layer Properties? Commented Sep 7, 2012 at 12:49
  • The API docs are for C++. Individual sip files need created for each aspect of the C++ API to be available via Python. Not all C++ classes and methods have been 'opened up' to Python (some probably never), but I don't see a reason why public (i.e. GUI) aspects of the new PAL stuff can't be. However, another developer will need to step in to help, as I'm quite the neophyte when it comes to writing sip files. So a feature request is the way to go.
    – dakcarto
    Commented Sep 7, 2012 at 15:45
  • What you are trying to do (programmatically set labels and other attributes) is interesting and a good example of why the Python access is needed. Please include a description of your use case in the feature request. Also, the new labeling options dialog now also shows up in the vector layer options dialog (in master branch). I believe it's access tool button may still remain on the tool bar, since its removal hasn't been discussed. The other tool buttons are interactive label manipulation tools, and as such should stay on the toolbar.
    – dakcarto
    Commented Sep 7, 2012 at 15:53
  • Done: Feature #6325 Commented Sep 10, 2012 at 10:50

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.