Sharing data between operators

I wrote an Operator which contain multiple properties. One Property is a CollectionProperty. I want to add items to the CollectionProperty via a button. As all buttons are Operators, I have to write an Operator to handle this. My problem is, how can the second operator access the data of the other one? Probably I’m missing some key understanding.

Something like this I want to achieve:


class OperatorB(bpy.types.Operator):
    def execute(self, context):
        # call add on collection of OperatorA

class OperatorA(bpy.types.Operator):
    collection = CollectionProperty(type=Foobar)

    def draw(self, context):
        layout = self.layout
        layout.operator("operator_a.add")

I’m also not sure if I really have to write an operator or if there are other ways to achieve that. I have also seen scripts which add properties to bpy.types.WindowManager or bpy.types.Scene which can then be accessed from different Operators. Is that the correct approach? In that case, is there a preferred type to add such properties?

At the end I want something (from the UI perspective) like the Modifiers tab, instead the drop down menu a button. Do I have to write Operator for closing, expand/collapse, etc.? I’ve looked at properties_data_modifiers.py, but it was not of much help, because the file mainly handles the drawing.

Any ideas or suggestions?

From what I understand (more experienced devs are invited to correct me otherwise),
an operator’s properties are not persistent, and are mostly useful when the operator is called.

In other words, I’m not sure if you can send values to an operator’s property from outside the operator’s own functions.

What I do is use a property group (that can hold as many props and methods as you need), which I then add as a property of the scene. You add (register) this prop group to scene’s object data type on the register function, and remove it in the unregister function.

These properties are persistent, can be accessed from any operator, panel or whatnot, and are also saved in the current blendfile’s scene (since this property group is actually added to the active scene as additional data).

You can find an example application of this idea in the random material assigner I wrote (it’s the shortest, simplest script I wrote that implements a property group for data sharing, which is why I linked to it).

The rand_mat_assigner class is what you should have a look at,
as well as the register and unregister functions that illustrate how to add it to the active scene.You can also see how it and the contained properties are accessed by the panel’s draw method:props = context.scene.face_assigner

Hope this helps!

You can pass the name of the object or scene that contains the collection upon operator invocation.


col.operator("op.my_operator", icon="INFO", text="").object_name_with_collection = "myObjectOrScene"

The in the operator that you are invoking create a string to receive the name.


class OBJECT_OT_add_remove_String_Items(bpy.types.Operator):
    bl_label = "Add or Remove"
    bl_idname = "op.add_remove_relay_entry"
    object_name_with_collection = bpy.props.StringProperty(default = "")
    
    def invoke(self, context, event):
        ob = bpy.data.objects.get(self.object_name_with_collection)
        .
        .
        .

you can construct the collection of collection property in the layout code, here’s an example:

http://git.blender.org/gitweb/gitweb.cgi/blender-addons-contrib.git/blob/974ac108b5df23b357b2fd66fa9c08e5563c0b04:/mesh_show_vgroup_weights.py#l407

Thanks a lot for the valuable information. Adding the information to the Scene would basically work, however I’m a bit reluctant to use that approach. As you said, the information is saved in the blend file, which in my case is absolutley not necessary. The Properties are all only used to construct an object.

The Properties I’m using are absolutlely temporary. So there is no need to save them anywhere. They are only used to create an object. Are there other ways then the one described to achieve that?

@CoDEmanX I’m not exactly sure how your advice could help me

My example shows how you can pass a variable amount of properties on to an operator, the source could be a collection of another operator.

However, it seems like you actually want to store your temporary data at a global level, and since you don’t want to persist it, bpy.types.WindowManager is the perfect fit:

Trouble getting windowmanager properties to save it’s contents with blend file

That’s good to know, @CoDEmanX!

@stante, to clarify - this means you can add your property group to the window manager data type instead of the scene type, and it won’t be saved to the blendfile (but will still allow you to share data between ops, panels, etc).

Now I got it. Thanks a lot for the valuable information.