When I run
import bpy
bpy.ops.wm.read_homefile()
and then I replace the above with this (in the same text data block)
import bpy
rrr = bpy.ops.object.select_all(action='SELECT')
print("select_all result:", rrr)
print(">>>>>>>>>> bpy.context:", bpy.context)
print(">>>>>>>>>> bpy.context.object:", bpy.context.object)
print(">>>>>>>>>> bpy.context.object.name:", bpy.context.object.name)
and run it, I get this
select_all result: {'FINISHED'}
>>>>>>>>>> bpy.context: <bpy_struct, Context at 0x000000EEA420B5C8>
>>>>>>>>>> bpy.context.object: <bpy_struct, Object("Cube")>
>>>>>>>>>> bpy.context.object.name: Cube
However, when I run this (same code but merged)
import bpy
bpy.ops.wm.read_homefile()
rrr = bpy.ops.object.select_all(action='SELECT')
print("select_all result:", rrr)
print(">>>>>>>>>> bpy.context:", bpy.context)
print(">>>>>>>>>> bpy.context.object:", bpy.context.object)
print(">>>>>>>>>> bpy.context.object.name:", bpy.context.object.name)
I get this
select_all result: {'PASS_THROUGH'}
>>>>>>>>>> bpy.context: <bpy_struct, Context at 0x000000EEA420B5C8>
Traceback (most recent call last):
File "\Text", line 7, in <module>
AttributeError: 'Context' object has no attribute 'object'
Why does that happen?
Is there a way to make the code after bpy.ops.wm.read_homefile()
work "normally"?
Edit:
It seems that bpy.ops.wm.read_homefile()
effectively "clears" the context - the bpy.context.area
is None
.
So the new question is how to bring the context back to the correct area?
Edit 2:
I have found a workaround that searches for 3D View area and makes it current context - and here is the dubious part - by calling bpy.ops.screen.screen_full_area()
:
import bpy
bpy.ops.wm.read_homefile()
havesetthecontext = False
for window in bpy.context.window_manager.windows:
screen = window.screen
for area in screen.areas:
print("area=", area)
if area.type == 'VIEW_3D':
override = {'window': window, 'screen': screen, 'area': area}
bpy.ops.screen.screen_full_area(override) # toggle to maximize
bpy.ops.screen.screen_full_area() # toggle back (must not use overridden context, else it will crash!)
havesetthecontext = True
break
if havesetthecontext:
rrr = bpy.ops.object.select_all(action='DESELECT')
print("select_all result:", rrr)
print(">>>>>>>>>> bpy.context:", bpy.context)
print(">>>>>>>>>> bpy.context.object:", bpy.context.object)
print(">>>>>>>>>> bpy.context.object.name:", bpy.context.object.name)
else:
print("Could not set the context to 3D View!")
Now, isn't there a way to set a context directly, something like bpy.context.set(override)
?
Edit 3:
The above workaround is unstable (occasionally crashes Blender) unless Load UI is disabled.
So, add this line before calling bpy.ops.wm.read_homefile()
:
bpy.context.user_preferences.filepaths.use_load_ui = False
That, of course, kind of kills the purpose of reloading startup file, unfortunately.
Oh, and the same issues appear when calling read_factory_settings()
.
When I run the screen_full_area() stuff from load_handler
then it does not crash, however, in the "main" code the bpy.context.area
is still None
- and when I do screen_full_area() stuff there too, it crashes again.
I suspect that crashing is due to some code in screen_full_area(), not the context changing, so we are back to the question is there a way to set the context directly?