4
$\begingroup$

I'm doing simple handler script that gets appended to bpy.app.handlers.frame_change_post.

Every time I do a changes to it and hit Alt+P it registers itself again with a new version. after a bit I have 10 of the scripts running happily on every frame change.

How can I get rid of the old running versions without closing and reopening Blender, which seems to be the only option now?

I tried adding unregistering with bpy.app.handlers.frame_change_post.remove() but that is just throwing an error as if my script wasn't on the list. while at the same time print(bpy.app.handlers.frame_change_post) is showing my function name there in growing numbers :)

so, what's the best practice developing and running these?

thanks.

.b

$\endgroup$
6
$\begingroup$

In simple cases when you're not having to deal with other handlers, you can clear all handlers before adding new ones:

bpy.app.handlers.frame_change_post.clear()

However for projects which are already using handlers, you may not want to remove everyone elses handlers, and instead replace only a handlers the script added.

Currently we don't have a convenient way to handle this, or at least Python doesn't make it so easy to reference a function defined in a previous execution.

This example script shows how the functions name and module can be used, append_function_unique is a function to append and remove previous instances.

import bpy

def append_function_unique(fn_list, fn):
    """ Appending 'fn' to 'fn_list',
        Remove any functions from with a matching name & module.
    """
    fn_name = fn.__name__
    fn_module = fn.__module__
    for i in range(len(fn_list) - 1, -1, -1):
        if fn_list[i].__name__ == fn_name and fn_list[i].__module__ == fn_module:
            del fn_list[i]
    fn_list.append(fn)


def my_function(scene):
    print(scene)

def register():
    append_function_unique(bpy.app.handlers.frame_change_post, my_function)

if __name__ == "__main__":
    register()

Note: This is isn't such a problem for modules (add-ons or scripts you import). However scripts you run directly will use a module name of __main__. This means if you run multiple scripts directly, there may be function naming collisions - which is why this solution isn't ideal.

| improve this answer | |
$\endgroup$
0
$\begingroup$

While developing in the text editor I tend to use bpy.app.handlers.frame_change_post.clear() to remove all handlers, but this may conflict with other scripts as it won't just remove the functions you appended.

If you want to use .remove() then you need to specify the function that you originally appended to the handler. E.g. if you originally did: bpy.app.handlers.frame_change_post.append(my_function_name) you would do bpy.app.handlers.frame_change_post.remove(my_function_name) to remove it.

| improve this answer | |
$\endgroup$
  • $\begingroup$ thanks, the bpy.app.handlers.frame_change_post.remove(my_function_name) I tried to use, but all I got was error: ValueError: list.remove(x): x not in list $\endgroup$ – basse Jun 1 '16 at 14:07
  • $\begingroup$ @basse I think maybe if you use clear() to clear everything out then you will be able to use remove() after that. $\endgroup$ – Ray Mairlot Jun 1 '16 at 14:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.