I’m using latest 2.91 build. I create a new scene with new_scene = bpy.data.scenes["New Scene"].copy()
. After this I want to set context.scene
to the new scene. I have tried bpy.context.window.scene = new_scene
but it didn’t affect bpy.context.scene
variable (and since it is read-only, I cannot set it directly).
I also tried bpy.ops.scene.new(type="LINK_COPY")
and it works but only in Python Console or if I put it in startup code of my addon. It then sets bpy.context.scene
to the new scene. But if I call it after the user clicks a button, it sets only bpy.context.window.scene
but bpy.context.scene
still refers to the old scene. Very strange.
To summurize, this is what works as expected (but I cannot use this since I do not want to create new scene on addon initialization):
import bpy
bpy.ops.scene.new(type="LINK_COPY") # Assuming current scene is "Scene", this creates "Scene.001"
print(bpy.context.window.scene.name) # Output: Scene.001
print(bpy.context.scene.name) # Output: Scene.001
The above code still works as expected in execute()
function of operator_simple.py
template, but this is expected since it is calling bpy.ops.object.simple_operator()
right after registration (calling bpy.ops.object.simple_operator()
with bpy.ops.scene.new(type="LINK_COPY")
inside it from Python Console also works as expected).
This what does not work as expected:
new_scene = bpy.data.scenes[scene_original.name].copy()
bpy.context.window.scene = new_scene
print(bpy.context.window.scene.name) # Output: Scene.001
print(bpy.context.scene.name) # Output: Scene (still refers to the old scene)
And bpy.ops.scene.new()
does not work as expected either if called after the user clicks a button. Here is minimalistic example to reproduce the issue based on ui_panel_simple.py
template:
import bpy
class SCENE_OT_create_linked_copy(bpy.types.Operator):
bl_idname = "scene.create_linked_copy"
bl_label = "Create linked copy"
bl_description = "Create linked copy of current scene."
def execute(self, context):
bpy.ops.scene.new(type="LINK_COPY") # Assuming current scene is "Scene", this creates "Scene.001"
print(context.window.scene.name) # Output: Scene.001
print(context.scene.name) # Output: Scene (still refers to the old scene)
return {"FINISHED"}
class HelloWorldPanel(bpy.types.Panel):
"""Creates a Panel in the Scene properties window"""
bl_label = "Hello World Panel"
bl_idname = "SCENE_PT_hello"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "scene"
def draw(self, context):
layout = self.layout
row = layout.row()
row.operator("scene.create_linked_copy")
def register():
bpy.utils.register_class(SCENE_OT_create_linked_copy)
bpy.utils.register_class(HelloWorldPanel)
def unregister():
bpy.utils.unregister_class(SCENE_OT_create_linked_copy)
bpy.utils.unregister_class(HelloWorldPanel)
if __name__ == "__main__":
register()
Technically updating bpy.context.scene
is possible but it is not clear how to do this in general case. This is may have something to do with the fact that I’m trying to use bpy.ops.scene.new()
and its behavior changes somehow depending on from what part of the GUI it was called. But is there a way to do this without using ops
? Or trying to avoid using context
is the only way?