6

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?

bortran
  • 1,362
  • 1
  • 14
  • 27

1 Answers1

12

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.

Jaroslav Jerryno Novotny
  • 51,077
  • 7
  • 129
  • 218