Page MenuHome

Callback function for property in CollectionProperty gets collection reference passed, not itself
Closed, InvalidPublic

Description

The property callback update_func() receives a reference to the collection coll as the self-argument, not a reference to the property with the callback attached (an item in the collection). It is supposed to be like that?

import bpy

def update_func(self, context):
    print(self, context)

class PropGroup(bpy.types.PropertyGroup):
    pfloat = bpy.props.FloatProperty(update=update_func)

bpy.utils.register_class(PropGroup)

bpy.types.Scene.coll = bpy.props.CollectionProperty(type=PropGroup)

It makes it impossible to have dynamic properties in a collection, 'cause the calling property can't be determined.

Event Timeline

codemanx raised the priority of this task from to 90.
codemanx updated the task description. (Show Details)
codemanx edited a custom field.
codemanx added a subscriber: codemanx.
codemanx updated the task description. (Show Details)Apr 19 2014, 10:39 PM
codemanx updated the task description. (Show Details)Apr 20 2014, 1:34 PM

Hmm...I use this all the time and it seems to work for me.

For instance

def updateREGridParameter(self,context):
	print(self.x_count)
		
class cls_regrid(bpy.types.PropertyGroup):
	x_count = bpy.props.IntProperty(name="X Count", description="Count for X axis.", default = 1, min = 0, max = 256, update=updateREGridParameter)

This will print the value of x_count. If self is changed my AddOn will break. You can always create a unique update def for each prop you want to manage. Perhaps some additional information about the property name could be passed as well...? But self should remain self right?

Campbell Barton (campbellbarton) changed the task status from Unknown Status to Invalid.May 9 2014, 1:43 AM

In the example given, add the line:

print(repr(self), repr(context))

This prints out...

bpy.data.scenes['Scene'].coll[2] <bpy_struct, Context at 0x60b00000ad88>

From this test snippet, everything is working as expected:

import bpy

def update_func(self, context):
    print(self, context)
    print(repr(self), repr(context))

class PropGroup(bpy.types.PropertyGroup):
    pfloat = bpy.props.FloatProperty(update=update_func)

bpy.utils.register_class(PropGroup)

bpy.types.Scene.coll = bpy.props.CollectionProperty(type=PropGroup)

# test adding a prop
coll_item = bpy.context.scene.coll.add()
coll_item.pfloat = 4

# note coll_item is passed as `self` to update_func

coll_item is indeed passed to the callback. I wonder if a reference to pfloat should be passed instead however, because that is the property the callback is registered for.