I have a propertygroup class called "Variants" from which I created several variant objects. Now I'm struggling to add these existing objects to a collection in another class.

class variantStates(bpy.types.PropertyGroup):

    variantState: bpy.props.StringProperty()

class variant(bpy.types.PropertyGroup):

    variantType: bpy.props.StringProperty()
    variantName: bpy.props.StringProperty()
    # List of all possible states
    variantStates: bpy.props.CollectionProperty(type=variantStates)

class variantList(bpy.types.PropertyGroup):

    variantRef: bpy.props.PointerProperty(type=variant)

class variantSet(bpy.types.PropertyGroup):
    # This is a Variant Set. It will contain several variants and trigger them all together

    variantSetName: bpy.props.StringProperty()

    # Here I want to add the existing variants when I create the set
    variantSetVariants: bpy.props.CollectionProperty(type=variantList)

here is the snippet from the operator that should later add the variants to the set:

for variant in var:
        addedVariant = newSet.variantSetVariants.add()
        addedVariant.variantRef = variant

I use the same approach as with adding the states to the variant early, but now it tells me that the pointer is read-only. And I only get a new empty variant added to the list. I guess I'm not really knowing what the pointer does. How can I achieve this? I was following the logic of this post where this is done with a pointer to "bpy.types.Object" and it works perfectly:

How to get one UIList to control the contents of another UIList?


1 Answer 1


You can't do that : addedVariant.variantRef = variant

It is not possible to reassign a PointerProperty.

You'll have to manually copy the properties from the reference property group to the target property group.


for variant in var:    
    addedVariant = newSet.variantSetVariants.add()
    addedVariant.variantRef.variantType = variant.variantType
    addedVariant.variantRef.variantName = variant.variantName
    # etc.
    # It's a bit more involved to copy collection properties
    addedVariant.variantRef.variantStates.clear() # Ensure it's empty before copying
    for source_state in variant.variantStates:
        new_state = addedVariant.variantRef.variantStates.add()
        new_state.name = source_state.name  # This attribute is builtin. (no need to explicitely define it)
        new_state.variantState = source_state.variantState
        # etc.    
  • $\begingroup$ Thanks for your reply, but this way I only apply the values of my current variant to a new variant. They wouldn't have anything to do with each other, e.g. if I change the name , the original variant name wouldn't change. If you look at my example from the link it seems to be possible with bpy.types.Object to reassign the pointer because the code is working. I'm confused why this should work with scene objects but not with my own class. $\endgroup$
    – quirin
    Jun 12 at 11:18
  • $\begingroup$ Ah ,right, so to be a bit more clear, it is not possible to reassign a PointerProperty pointing to a PropertyGroup. You can however reassign a PointerProperty pointing to a bpy.types.Object. $\endgroup$
    – Gorgious
    Jun 12 at 11:54
  • $\begingroup$ So this is known exeption or why is this? Still dont fully get why this is not possible. So to do what I'm planning to do, I have to create scene objects and assign my property groups to them? Or is there a more elegant way? $\endgroup$
    – quirin
    Jun 12 at 12:55
  • 1
    $\begingroup$ Just adding (in case it is useful for someone), that is handy to loop through __annotations__ when copying/setting all values in a property group and set/get properties dynamically instead to manually set/add the logic of each property when you add a new prop to a PropertyGroup $\endgroup$
    – Ommadawn
    Sep 20 at 14:25
  • 1
    $\begingroup$ @Ommadawn good point ! Thanks for pointing it out $\endgroup$
    – Gorgious
    Sep 20 at 18:06

You must log in to answer this question.

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