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

1 Answer 1

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
    Commented Aug 11, 2021 at 22:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .