6
$\begingroup$

The code below works flawless, if e.g. triggered by a menu button in a 3D view.

        for area in bpy.context.screen.areas: 
          if area.type == 'VIEW_3D':
            for space in area.spaces:
                if space.type == 'VIEW_3D': 
                    space.viewport_shade = 'BOUNDBOX'

However, if I bundle it into a function and hook it to a handler, it returns a NoneType error:

@persistent
def allBound(dummy):
  for area in bpy.context.screen.areas: 
      if area.type == 'VIEW_3D':
        for space in area.spaces:
            if space.type == 'VIEW_3D': 
                space.viewport_shade = 'BOUNDBOX'

 bpy.app.handlers.render_pre.append(allBound)

Returns:

AttributeError: 'NoneType' object has no attribute 'areas'

How to solve this?

$\endgroup$
9
+100
$\begingroup$

Turns out that inside bpy.app.handlers.render_pre the context is different.

For example bpy.context.screen is None, bpy.context has no attribute active_object etc. Looks like its very limited when rendering.

What you have access to is bpy.context.window_manager. So modify your script like this and it should work:

import bpy

def allBound(scene):
    for window in bpy.context.window_manager.windows:
        for area in window.screen.areas: 
            if area.type == 'VIEW_3D':
                for space in area.spaces:
                    if space.type == 'VIEW_3D':
                        space.viewport_shade = 'BOUNDBOX'

bpy.app.handlers.render_pre.append(allBound)

Also this now works on a multi-monitor layout.

$\endgroup$
  • 2
    $\begingroup$ I know I shouldn't, but thank you, thank you sir, thank you so much! :) $\endgroup$ – bortran Apr 16 '15 at 13:15

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.