2

Is there any way have some more information of the prop from it's update function?

In the example below, unfortunately, self will point out to bpy.types.Scene, instead of the prop itself. so it seem at first glance that we cannot have any information of the props from the update function, and we are forced to have one update function per prop, instead of a single centralized update function that could work with every one the prop

(Note that We can have more information from set, but of course, it will create feedback loops if we change the prop value.. )

please prove me wrong

def update(self,context):
    print("what is this prop value?")
    print("what is this prop api?")
    print("what is this prop name?")
    return None

bpy.types.Scene._prop : bpy.props.FloatProperty(default=1.0 , name="Prop", update=update) bpy.types.Scene._prop_this : bpy.props.FloatProperty(default=1.1 , name="Prop This", update=update) bpy.types.Scene._prop_that : bpy.props.FloatProperty(default=1.2 , name="Prop That", update=update) bpy.types.Scene._prop_another : bpy.props.FloatProperty(default=1.3 , name="Prop Another", update=update)

Fox
  • 1,892
  • 18
  • 48
  • 1
    maybe self._prop? What do you want to do exactly? – lemon Dec 14 '20 at 12:11
  • I want to get the self._prop information, as the update function is centralized, it seem impossible to get prop from where the update was launched – Fox Dec 14 '20 at 12:23
  • If you want to do something different per prop, why defining several update functions is not the way? – lemon Dec 14 '20 at 12:31
  • No, i want to do the same thing for each properties, creating one update function per properties seem absurd, but it seem that blender API leave us no choice – Fox Dec 14 '20 at 12:53

1 Answers1

5

Make a generic function to create your update method.

There is another answer very similar to this by @pinkvertex could not find it.

Instead using one function as the update method, create a method factory to pass properties to.

Example code, and example run (pretty self-explanatory),

import bpy
from bpy.props import FloatProperty
from bpy.types import Scene

def update(prop): def update(self, context): print(f"Update {prop} of {self}") return None return update

for prop in ("prop_this", "prop_that", "prop_another"): setattr( Scene, prop, FloatProperty( default=1.0, name="Prop", update=update(prop) ) )

Sample run.

>>> C.scene.prop_this
1.0

>>> C.scene.prop_this = 4 Update prop_this of <bpy_struct, Scene("Scene") at 0x7fc97bff8008>

>>>

Two things re question code,

  • The properties are assigned to the type, not as an annotation. Use annotations in a class definition.

    Cannot create a private variable prefixed with underscore.

     >>> bpy.types.Scene._prop = bpy.props.FloatProperty()
     Traceback (most recent call last):
     File "<blender_console>", line 1, in <module>
     ValueError: bpy_struct "Scene" registration error: _prop could not register because the property starts with an '_'
    
batFINGER
  • 84,216
  • 10
  • 108
  • 233
  • 1
    This function factory was a grat idea! thanks a lot! – Fox Dec 14 '20 at 15:48
  • Finally found the dupe & noticed I was one of two to mark it as a favourite. Note the lambda def in comments below PV answer. Handy for setting up generic handlers too. https://blender.stackexchange.com/a/133129/15543 – batFINGER Dec 14 '20 at 15:56