5
$\begingroup$

I have a problem with app handlers in Blender and Python. I am trying to write a script that can start a render and automatically upload it when it finished.

So far it works, but now I want to see the render process as well.

I tried bpy.ops.render.render('INVOKE_DEFAULT'), but that doesn't wait until the render is finished until executing the next parts of the code, where the upload happens.

After a bit of search I stumbled across app handlers, which seem to be what I need. So I tried this:

import bpy

def my_handler(scene):
    print("render complete")

bpy.ops.render.render('INVOKE_DEFAULT')

def register():
    bpy.app.handlers.render_complete.append(my_handler)

def unregister():
    bpy.app.handlers.render_complete.remove(my_handler)


if __name__ == '__main__':
    register()

When I press Alt+P in Blender's Text Editor, it works fine at first. But when I try it a second and third time, it starts printing "render complete" multiple times at once in the console. Each time I run it, it prints one time more. So I guess something is wrong here, and if the simple printing doesn't work, I rather don't try to use this app handler to upload the render result ;)

Anyone has an idea what's going on?

$\endgroup$
0
10
$\begingroup$

It looks like you're adding the render handler multiple times.

If you want a one-off handler, you can do this:

def my_handler(scene):
    print("render complete")
    bpy.app.handlers.render_post.remove(my_handler)

... you'll also want to change unregister not to error when the handler has run.

def unregister():
    if my_handler in bpy.app.handlers.render_post:
        bpy.app.handlers.render_complete.remove(my_handler)

Note: if you end up writing many one-off handlers, you might want to investigate writing a decorator, so a new handler could look like:

@call_once(bpy.app.handlers.render_post)
def my_handler(scene):
      print("render complete")

... where call_once can handle details to avoid a lot of repetition.

$\endgroup$
1
  • $\begingroup$ I'm in a similar situation as OP. I need a way of holding a 'for' loop until the render is over. I can't find a way of doing so, and blender crashes. $\endgroup$
    – J.Nada
    Aug 11 at 22:09

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.