How set custom value in custom list

I have created a ListAction that needs a custom index, so I have defined tag as the code below.


class UilistActions(bpy.types.Operator):
    bl_idname = "custom.list_action"
    bl_label = "List Action"
    tag = bpy.props.IntProperty()   # My custom value

The problem is how can I set the value of tag? I have this code for the UI.


row.template_list("UlItems", "", group, "custom", group, "custom_index", rows=rows)
col = row.column(align=True)
col.operator("custom.list_action", icon='ZOOMIN', text="").action = 'ADD'
col.operator("custom.list_action", icon='ZOOMOUT', text="").action = 'REMOVE'
col.separator()
col.operator("custom.list_action", icon='TRIA_UP', text="").action = 'UP'
col.operator("custom.list_action", icon='TRIA_DOWN', text="").action = 'DOWN'

Usually, I used this code to set the tag value, but this doesn’t work with Lists.


op = row.operator("setpivotbutton", text="", icon="EYEDROPPER")
op.tag = idx  # saves internal data

How can I set the tag value?

What’s the relation between the operator property “tag” and the UI list?

I have several items in a panel and each of them have therir own list, so I want to detect the item number in the panel for the UIList to do something like:


data =myarray[self.tag]

I have used before the tag in operators like buttons to use the same button with different situation, using tag as the falg that allow me to select the right one.

Do you see my point?

You might wanna add an update-callback to the UIList’s index property. It should be called every time the number of item changes (as well as index changes of course).

But I don’t want control the changes in the list items, but the list number in the panel (list 1, list 2, list 3, etc)

Do you mean the visible name of list entries, or like a label above the template list widget?

I’m going to explain my problem:

I have a custom property named “Group” and each group has a custom property named “List” that contains all items. I assign to one object an array of Groups, so I have Group[0], Group[1], etc… and for each “Group” I have “List”, so Group[0] has its List with several items, Group[1] equal, etc.

I have this code:


<b>class </b><b>UilistActions</b>(bpy.types.Operator):
    bl_idname = "custom.list_action"
    bl_label = "List Action"
    tag = bpy.props.IntProperty()

    action = bpy.props.EnumProperty(items=(('UP', "Up", ""), ('DOWN', "Down", ""),
                                           ('REMOVE', "Remove", ""), ('ADD', "Add", "")))

    <b>def </b><b>invoke</b>(self, context, event):
        mainobject = context.object
        mp = mainobject.MyCustomData[0]
        mg = mp.grps[self.tag]  # This is the line where I need the index of the group
        idx = mg.custom_index
        <b>try</b>:
            item = mg.custom[idx]
        <b>except </b>IndexError:
            <b>pass
</b><b>        else</b>:
            <b>if </b>self.action == 'DOWN' <b>and </b>idx &lt; len(mg.custom) - 1:
                item_next = mg.custom[idx + 1].name
                mg.custom_index += 1

            <b>elif </b>self.action == 'UP' <b>and </b>idx &gt;= 1:
                item_prev = mg.custom[idx - 1].name
                mg.custom_index -= 1

            <b>elif </b>self.action == 'REMOVE':
                info = 'Item %s removed from list' % mg.custom[mg.custom_index].name
                mg.custom_index -= 1
                mg.custom.remove(idx)

        <b>if </b>self.action == 'ADD':
            val = str(mp.allgrp)
            # Avoid duplication
            <b>for </b>i <b>in </b>mg.custom:
                <b>if </b>i.grp == val:
                    <b>return </b>{"FINISHED"}

            item = mg.custom.add()
            item.id = len(mg.custom)
            item.grp = val
            item.lstold = val
            mg.custom_index = (len(mg.custom) - 1)

        <b>return </b>{"FINISHED"}

In my code, I need the index of the group to detect the group item that contains the corresponding list.


    <b>def </b><b>invoke</b>(self, context, event):
        mainobject = context.object
        mp = mainobject.MyCustomData[0]
        mg = mp.grps[self.tag]  # This is the line where I need the index of the group

In the panel I have each group, with its UIlist.


<b>for </b>group <b>in </b>all_my_groups:
        # group contains the current group object
        # I need to pass a reference or index of group to this instance of the list
        rows = 3
        row = box.row()
        row.template_list("UlItems", "", group, "custom", group, "custom_index", rows=rows)

        col = row.column(align=<b>True</b>)
        col.operator("custom.list_action", icon='ZOOMIN', text="").action = 'ADD'
        col.operator("custom.list_action", icon='ZOOMOUT', text="").action = 'REMOVE'
        col.separator()
        col.operator("custom.list_action", icon='TRIA_UP', text="").action = 'UP'
        col.operator("custom.list_action", icon='TRIA_DOWN', text="").action = 'DOWN'

I have tried to pass the tag parameter to the class, but I can’t.

So Group is a CollectionProperty(), which defines a property “list” in a class derived from PropertyGroup, but is it also a CollectionProperty()? (a collection of collections)

@codexman Yes, you are right a collection of collections. What I need is to pass the reference of the “parent” collection to the instance of the list to get all items as you can see in the code above. Maybe if instead of passing the index I could get the parent collection with some function (something like: group = self.get_parent()), but I don’t know if this is possible in Python.

Attachments


I have found the solution, really it was easy :slight_smile:


col = row.column(align=<b>True</b>)
op = col.operator("custom.list_action", icon='ZOOMIN', text="")
op.action = 'ADD'
op.tag = idx

Oh well, sometimes it’s easy :wink:

I remember it being very hard in menus to determine the parent menu items however, if all children use the same menu definition. I believe I had to use dynamic menu creation, but it stopped working 1-2 versions later in Blender…