Dynamic EnumProperty values changing unexpectedly
The EnumProperty properties represent underlying integer values - 1, 2, 3, etc. - and the 'enum_items' function provides the conversion between the numbers and the textual description (in this case the names of the objects in the scene).

The problem is that the list returned by the 'enum_items' function is changing when meshes are added or removed from the scene so that the values held in the EnumProperty properties no longer corresponds with the same object. This means that as the sequence of objects changes, the corresponding enumeration value also changes, resulting in the values being reassigned.

The 'enum_items' list is currently being built directly from the context.scene.objects list and each item is appended to the list. When objects are added to the scene they are added to the start of the list of objects - hence they are appearing at the start of the list and this is shuffling the objects along the list - so what was in position 1 is now in position 2, what was in position 2 is now in position 3, and so on. A simple dirty fix to this would be to change the order of the list - by inserting each one at the beginning rather than appending them at the end. ie,

Change :

items.append( (obj.name, obj.name, "") )


to :

items.insert(0, (obj.name, obj.name, "") )


You should now find that adding new objects to the scene no longer upset the existing EnumProperties. However, deleting objects still presents a problem - unless it's always the 'newest' object that is deleted, although even then you have the problem that the EnumProperty still points to the same (empty) slot of the list (so if a new object is added again then it will be immediately populated into the same slot - rather than the slot being initially blank!).

To address this you can assign a unique identifier when adding items to the list (in which case it no longer matters on the order in the list since the uniqueid is used to maintain consistency regardless of the sequence) :

items.append( (obj.name, obj.name, "", &lt;uniqueid&gt;) )


This can be achieved as follows :

import bpy

# NEW CODE - Create a list to assign unique identifier to each mesh name
enum_items_store = []

def enum_items(self, context):

    items = []
    for obj in context.scene.objects:
        if obj.type == 'MESH':

            # NEW CODE
            # Scan the list of IDs to see if we already have one for this mesh
            maxid = -1
            id = -1
            found = False
            for idrec in enum_items_store:
                id = idrec[0]
                if id &gt; maxid:
                    maxid = id
                if idrec[1] == obj.name:
                    found = True
                    break

            if not found:
                enum_items_store.append((maxid+1, obj.name))

            # AMENDED CODE - include the ID
            items.append( (obj.name, obj.name, "", id) )

    return items

class SomePropertyGroupEntry(bpy.types.PropertyGroup):
    mesh_obj = bpy.props.EnumProperty(items=enum_items)
    val = bpy.props.IntProperty()

class SomePropertyGroup(bpy.types.PropertyGroup):
    collection = bpy.props.CollectionProperty(type=SomePropertyGroupEntry)
    index = bpy.props.IntProperty()

class SCENE_UL_list(bpy.types.UIList):
    def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
        if self.layout_type in {'DEFAULT', 'COMPACT'}:
            layout.prop(item, "name", text="")
            layout.prop(item, "mesh_obj", text="")
        elif self.layout_type in {'GRID'}:
            layout.alignment = 'CENTER'
            layout.label(text="", icon_value=icon)

class SCENE_OT_list_populate(bpy.types.Operator):
    bl_idname = "scene.list_populate"
    bl_label = "Populate list"

    def execute(self, context):
        context.scene.prop_group.collection.clear()
        for i in range(3):
            item = context.scene.prop_group.collection.add()
            item.name = "item"+str(i)
        return {'FINISHED'}

class SCENE_PT_list(bpy.types.Panel):
    bl_label = "UIList Panel"
    bl_idname = "SCENE_PT_list"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "scene"

    def draw(self, context):
        self.layout.operator("scene.list_populate")
        self.layout.template_list("SCENE_UL_list", "", context.scene.prop_group, "collection", context.scene.prop_group, "index")

def register():
    bpy.utils.register_module(__name__)
    bpy.types.Scene.prop_group = bpy.props.PointerProperty(type=SomePropertyGroup)

def unregister():
    bpy.utils.unregister_module(__name__)
    del bpy.types.Scene.prop_group

if __name__ == "__main__":
    register()


Note that mesh names are never removed from the list of IDs. This means that the unique identifier will only be re-used if a mesh is re-created or renamed to the same name as a previous mesh.