6
$\begingroup$

I am trying to pass a collection as parameter of an operator, but I have following issue :

AttributeError: bpy_struct: attribute "collection" from OBJECT_OT_example_op" is read-only

Here is my example code :

import bpy

class Item(bpy.types.PropertyGroup):
    name = bpy.props.StringProperty(name="Name")

class ExamplePanel(bpy.types.Panel):
    bl_label = "ExamplePanel"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'TOOLS'
    bl_category = "Example"

    @classmethod
    def poll(self, context):
        return True

    def draw(self, context):
        layout = self.layout
        layout.operator("object.example_op", text="Test").collection = bpy.context.scene.collection

class ExampleOperator(bpy.types.Operator): 
    bl_idname = "object.example_op"
    bl_label = "Example Operator"
    bl_options = {'REGISTER'}   

    collection = bpy.props.CollectionProperty(type=Item)

    @classmethod
    def poll(self, context):
        return True

    def execute(self, context):
        for item in self.collection:
            print(item.name)
        return {'FINISHED'}

def register():
    bpy.utils.register_class(Item)
    bpy.types.Scene.collection = bpy.props.CollectionProperty(type=Item)

    it = bpy.context.scene.collection.add()
    it.name = "item1"
    it = bpy.context.scene.collection.add()
    it.name = "item2"   

    bpy.utils.register_class(ExampleOperator)
    bpy.utils.register_class(ExamplePanel)


if __name__ == "__main__":
    register()

Any suggestions ? Tried with PointerProperty, but don't know exactly how to use it, and got same error.

Thanks :)

$\endgroup$
2
  • 1
    $\begingroup$ Not sure how to pass collection prop to an operator in the layout. My suggestion is change for item in self.collection to for item in context.scene.collection ie use the scene collection in the operator. You can however use bpy.ops.object.example_op(coll=[{"name":"Goose"}, {"name":"Herman"}]) to pass the collection to the operator... coll=scene.collection will throw an error too. $\endgroup$
    – batFINGER
    Commented Mar 9, 2016 at 16:52
  • $\begingroup$ Thanks for your answer. I can't use directly context.scene.collection in my case. Will work in this example, but my real case is more complicated, and is not a property of bpy.types.Scene. $\endgroup$
    – Julien
    Commented Mar 10, 2016 at 7:23

1 Answer 1

4
$\begingroup$

Campbell give me an answer in Blender mailing list. Here is the proposed solution :

import bpy

class Item(bpy.types.PropertyGroup):
    name = bpy.props.StringProperty(name="Name")

class ExamplePanel(bpy.types.Panel):
    bl_label = "ExamplePanel"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'TOOLS'
    bl_category = "Example"

    @classmethod
    def poll(self, context):
        return True

    def draw(self, context):
        layout = self.layout
        op = layout.operator("object.example_op", text="Test")
        for src_item in bpy.context.scene.collection:
            dest_item = op.collection.add()
            dest_item.name = src_item.name


class ExampleOperator(bpy.types.Operator): 
    bl_idname = "object.example_op"
    bl_label = "Example Operator"
    bl_options = {'REGISTER'}   

    collection = bpy.props.CollectionProperty(type=Item)

    @classmethod
    def poll(self, context):
        return True

    def execute(self, context):
        for item in self.collection:
            print(item.name)
        return {'FINISHED'}

def register():
    bpy.utils.register_class(Item)
    bpy.types.Scene.collection = bpy.props.CollectionProperty(type=Item)

    it = bpy.context.scene.collection.add()
    it.name = "item1"
    it = bpy.context.scene.collection.add()
    it.name = "item2"   

    bpy.utils.register_class(ExampleOperator)
    bpy.utils.register_class(ExamplePanel)


if __name__ == "__main__":
    register()
$\endgroup$
1
  • $\begingroup$ This example should be in the official documentation. Great example. $\endgroup$
    – satishgoda
    Commented Jun 10, 2017 at 8:13

You must log in to answer this question.

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