How to trigger an event on some property change

Hi, i’ve been searching a lot for a solution, but never got straight answer, and i know that this should a pretty common task to encounter. So - how can i let my script know (or how can i make it “listen” if you will) if some specific datablock has been changed. I know there is a “tag” property for most datablocks, but i just can put it in a good use.

You can do it like this:


import bpy

def myprop_update(self, context):
    if self.myproperty == "Yo":
        self.myproperty += " man!"
    
    print("My property is:", self.myproperty)

bpy.types.Scene.myproperty = bpy.props.StringProperty(
    name="My Property",
    update=myprop_update
)

And then if you write these into console you will see the results.


>>> bpy.context.scene.myproperty = "Hi"
My property is: Hi

>>> bpy.context.scene.myproperty = "Yo"
My property is: Yo man!
My property is: Yo man!

You can see in this example that you can handle the values of the property more carefully. For more information check here: http://www.blender.org/api/blender_python_api_2_66_4/bpy.props.html?highlight=bpy.props#bpy.props.StringProperty

Thanks for the answer, but this is not exactly what I looking for. First of I didn’t meant custom properties, but any property in given datablock. And second - i need to know if datablock was changed, and not a specific property.

Ok, it looks like i found a way to check if some datablock has been affected. You have to hook up a handler on scene_update_pre/post event that’ll check .is_updated property of datablock, BUT unfortunately for some reason it only works with certain datablock (to be specific - those datablocks that being changed affects rendering directly). But I need to figure out a way to check if given action has been changed. If anyone have thoughts regarding this problemm - you’re welcome.

You can not attach callbacks to existing properties, and is_updated / is_updated_data aren’t really meant to be True on property changes. They are intended to be used with the render API afaik.

To quote the API docs:

  • Define callbacks or listeners to be notified when data is changed.

http://www.blender.org/api/blender_python_api_2_73_release/info_quickstart.html

You could only register secondary properties and store previous property states there. Then compare on every scene update callback if they changed. But that’s a lot of overhead…

But that’s a lot of overhead…

Exactly. I was thinking of kinda crazy idea to calculate some average sum of values in actions in all fcurves with some algorithm that approximates values somehow instead of iterating over each key, and then compare these calculations with ones from previous update call… buuut my math skills is pretty low and brute force approach is… well, it’s to brutal.