[Gimp-developer] Python-fu GIMP Layer "parent" property error



As stated at http://www.gimp.org/bugs/ I'm supposed to mention issues
here before throwing them into the tracker so here goes.

Working on a plugin that does some layer manipulation and kept
encountering the error:
AttributeError: 'gimp.Layer' object has no attribute 'layers'
when trying to access the layer structure in a tree-like fashion to
find "sibling" layers in the same grouplayer/layergroup. After being
puzzled, I found the issue, which seems to essentially be that the
"parent" attribute of a layer automatically "upcasts" to gimp.Layer,
rather than yielding a gimp.GroupLayer, as I think should be expected.

The behavior can be reproduced as follows from Python console in GIMP 2.8.8:
image = gimp.image_list()[0]
image.layers[0].layers[0].parent.layers # again with the result:
AttributeError: 'gimp.Layer' object has no attribute 'layers'

Assuming an image's layer-structure is similar to:
[root image]
+--------GROUPLAYER ZERO
+--------+--------LAYER ZERO OF ZERO
+--------GROUPLAYER ONE
+--------+--------LAYER ZERO OF ONE
+--------+--------LAYER ONE OF ONE
+--------LAYER BACKGROUND

From the console we have a hint as to why this is.
image.layers[0]
<gimp.GroupLayer "GROUPLAYER ZERO">
image.layers[0].layers[0].parent # should return the same layer as above but gives
<gimp.Layer "GROUPLAYER ZERO">

I haven't seen this on the bugtracker nor was I able to find
discussion about it on the listserv archive. I assume it is a
platform-independent bug. Can anyone confirm that? I develop on
Windows XP at present.

Workarounds for this bug exist I'm not in love with them (inelegant).
Regardless, a sketch of what might work without using globals:

def get_all_layers(parent):
    """-> list. recursively get all layers from either an image, or a GroupLayer
    Proceeds depth-first.
    """
    container=[]
    for layer in parent.layers:
        container.append(layer)
        if hasattr(layer,"layers"):
            container.extend( get_all_layers(layer) )
    return container

def get_parent(child):
    if hasattr(child,"parent"):
        for layer in get_all_layers(child.image):
            if layer.name==child.parent.name: return layer
            #^ layer will have the proper data-type of
gimp.GroupLayer, so return it.
            #^.. We do this because child.parent yields a gimp.Layer,
which is undesired.
    else:
        return child.image # if we're already top-level, parent must
just be the image.

Cheers
- Seldom


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]