2
$\begingroup$

I have a scene with custom properties, written in a class, I am now able to access the values of these properties, I would like to know how to write these values in a new scene. For example:

This is the properties:

class MySceneProperty(bpy.types.PropertyGroup):

    my_bool: BoolProperty(default=false)
    my_int: IntProperty(default=0)
    my_float: FloatProperty(default=0.0)

def register():

    bpy.types.Scene.scene_prop = bpy.props.PointerProperty(type=MySceneProperty)

I would like to create a new scene and use the previous parameters, as they could be changed by the default value, so the approach would be.

def my_function(self,context):
    first_scene = bpy.context.scene

    ###get attributes:
    for key in first_scene.scene_prop.__annotations__.keys():
        first_attributes = getattr(first_scene.scene_prop, key)

    ###new scene creation:
    new_scene= bpy.data.scenes.new("New scene")    
    context.window.scene = new_scene

    #Here I would like to set the attributes of the previous scene but I 
    #don't know how to do it

    ###set attributes???  (this obviously produces an error)

    for key in new_scene.scene_prop.__annotations__.keys():
        setattr(new_scene.scene_prop, key) = first_attributes 
$\endgroup$

1 Answer 1

3
$\begingroup$

Free you mind and think simple: new_scene.scene_prop.my_bool = first_scene.scene_prop.my_bool

If however you need to batch-set properties from a list of strings, like the __annotations__.keys() method returns, you can use Pythons setattr and getattr methods:

for s in first_scene.scene_prop.__annotations__.keys():
    setattr(new_scene.scene_prop, s, getattr(first_scene.scene_prop, s))

So in the end, your function from above could be turned into:

def my_function(self, context):
    first_scene = bpy.context.scene

    ### new scene creation comes before the loop:
    new_scene= bpy.data.scenes.new("New scene")    
    context.window.scene = new_scene

    ### copy attributes from source to target scene:
    for key in first_scene.scene_prop.__annotations__.keys():
        source_attribute = getattr(first_scene.scene_prop, key)
        setattr(new_scene.scene_prop, key, source_attribute)
$\endgroup$
8
  • $\begingroup$ Thanks aliasguru for the reply! this was my first thought, but I really have many properties, and I'm continuing to add them, so I would have to compile all the properties every time, I'd like to have a "faster" way of having all the properties and precisely I came across this ".__ annotations __. keys ():" "getattr ()" which gives me all the attributes I need, I just want to understand how to set them on the new scene without having to compile 1x1 $\endgroup$
    – Noob Cat
    Sep 6, 2019 at 5:57
  • 1
    $\begingroup$ @Pastrokkio updated my answer $\endgroup$
    – aliasguru
    Sep 6, 2019 at 6:01
  • $\begingroup$ Unfortunately I get this error: TypeError: 'builtin_function_or_method' object is not iterable $\endgroup$
    – Noob Cat
    Sep 6, 2019 at 6:19
  • 1
    $\begingroup$ @Pastrokkio Was typing this on my phone in a rush this morning, I have updated the code now, should work $\endgroup$
    – aliasguru
    Sep 6, 2019 at 11:13
  • 1
    $\begingroup$ @Pastrokkio annotations have been introduced with Blender 2.80, so they don't exist in 2.79. Before that I used to deal with the bl_rna methods. bpy.context.scene.scene_prop.bl_rna.properties.keys() etc. should get you started there. But this really is a different question, so please ask a new one in case. $\endgroup$
    – aliasguru
    Sep 26, 2019 at 16:08

You must log in to answer this question.

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