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$

1 Answer 1

12
+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$
1
  • 3
    $\begingroup$ I know I shouldn't, but thank you, thank you sir, thank you so much! :) $\endgroup$
    – bortran
    Commented Apr 16, 2015 at 13:15

You must log in to answer this question.

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