2
$\begingroup$

I have the following data in my script:

  • Any mesh object, referenced as context.active_object
  • bpy.types.Object.markers = CollectionProperty(type = Marker), where Marker is a class containing just id, name and single vector to store location
  • ui with the UIList, on which I draw elements from the markers list

I have also a number of classes for making data, addings objects, etc. The script allows to easily click on a mesh and add new empty in the 3dcursor location. I have all those empties parented to the object, and I'm collecting their names in markers collection. All items for a mesh object is draw in a list using UIList. Here is my draw_items function:

class MarkerList(UIList):
    def draw_item(self,context,layout,data,item,icon,active_data,active_progname):
        if not item or item.name == '':
            layout.row().label('no name for id'+str(item.id),icon='CANCEL')
        else:
            if item.name in bpy.data.objects.keys():
                ob = bpy.data.objects[item.name]
                layout.prop(data=ob,property='name',icon='PINNED',emboss=False,text='') 
            else:
                lab = layout.label(icon='QUESTION',text=item.name)

Now, the UIList is showing props using their names (data=ob, property='name'). That's OK, BUT, if somebody double click the name, it could be changed. This change also changes the name of the real empty object. I would like to update also markers list for that change, but I do not know how.

So, IS there any kind of 'update' function which is called after changing the name of the prop from the list? Or 'notify', or whatever. I would like to keep markers as a simple list of names and locations, but also I would like to allow user to change their names. If that's not possible, alternative question is: how to block names change in the UIlist?

Also, sorry for poor formulated question, I had no better idea how to ask how to detect name change of objects changed in UIList and invoking some additional action after that (ie. updating my markers list name).

Here is the UIList:

enter image description here

The counter is just a IntProperty added to bpy.types.Object.

Here is the name double clicked in the list:

enter image description here

It is automatically selected and user can change the name of the real object.

Here is the name changed by the user:

enter image description here

After this change, the real name of the object is changed, which is desired. I don't know, how to update the name in my own list, so I put the condition:

if item.name in bpy.data.objects.keys():

in draw_items to at least show this in the list. But I want to update my own data instead. After name is changed, the following info appears in the info window:

enter image description here

My list is looking like that at this stage:

enter image description here

My outliner is showing the change of new name of the object parented:

enter image description here

So, any advice will be most welcome. I can either block this editing behaviour (how?) or allow to detect name change of specific item and update markers data respectively. The script is going to manage thousands of those objects.

$\endgroup$

1 Answer 1

3
$\begingroup$

In draw_item() you pass item and then use if item.name in bpy.data.objects.keys() - if you rename a key in bpy.data.objects and it no longer compares to item.name then that tells me that item is at least a copy or part copy of the data in bpy.data.objects.

This means the fix will be to update the name in both bpy.data.objects and item.

The fix will depend on what is in the rest of your code. Maybe an extra refresh of the data in item. One possibility is using bpy.props, by utilising the update feature of bpy.props you can have a small function that will update both your item data and the objects name property, that would mean having the list show your list of item properties not bpy.data.object properties.

$\endgroup$
3
  • $\begingroup$ Yes, that's exactly what I want to. However, I do not know how to react to the event of change name in list element, and how then apply this to change something another. I have a simple elements on the list, taken from the class which inherits from PropertyGroup. Should I define some method in that class? If that's possible, then I see some light in the tunnel. $\endgroup$
    – piotao
    Apr 25, 2016 at 18:18
  • $\begingroup$ It seems that documentation here blender.org/api/blender_python_api_current/… is telling nothing about update method :( $\endgroup$
    – piotao
    Apr 25, 2016 at 18:20
  • $\begingroup$ Ahh, I see!!! Only now I noticed that you've already provided me with the right documentation piece, thank you. $\endgroup$
    – piotao
    Apr 25, 2016 at 18:21

You must log in to answer this question.

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