0
$\begingroup$

I would like to have a list in the preferences of my Add-On where the content of the list is read from a file. (And therefore the length of the list is not known.) In this list I would like to have a check mark icon for each list item and only one should be selected. Both the list as well as the selected item of the list should be saved with the Add-On's preferences.

Normally such a list would be done with a PropertyGroup and a UIList. But I don't know how to do it in the Preferences as it is a class of it's own. Can someone help me to show how to achieve this?

PropertyGroup for storing the data from file:

class Library_List(bpy.types.PropertyGroup):
    lib_name: bpy.props.StringProperty(name ='lib_name')
    lib_last_mod: bpy.props.IntProperty(name ='lib_last_mod') 

Class for reading the file:

class ReScan_Root_Library(bpy.types.Operator):
    bl_idname = "panel.rescan_root_library"
    bl_label = "Rescan Library"
    
    def execute(self, context):
        ...
        LibList = open(LibList_path, "r")
        for x in LibList:
            if not re.match(r'#', x) and not re.match(r'\n', x):
                in_temp = x.split()
                Lib_In = bpy.context.scene.lib_list.add()
                Lib_In.lib_name = in_temp[0]
                Lib_In.lib_last_mod = int(in_temp[1])        
    return {'FINISHED'}

I defined a UIList:

class CUSTOM_UL_items(UIList):
    def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
        split = layout.split(factor=0.3)
        split.label(text=item.lib_name)
        split.label(text=str(item.lib_last_mod))
    def invoke(self, context, event):
        pass   

And trying to add it to the preferences interface:

scn = bpy.context.preferences.addons['My_AddOn'].preferences
row.template_list("CUSTOM_UL_items", "", scn, "lib_list", scn, "", rows=2)

I try to define lib_list in the init as:

bpy.types.Preferences.lib_list = bpy.props.CollectionProperty(type=Library_List)

but this is obviously wrong as I get the message:

ui_template_list_data_retrieve: Property not found: PREF_PT_Preferences.lib_list

How do I define lib_list? If I define it as bpy.types.scene.lib_list I also get an error message. I have CollectionProperties in my scene and they work fine. I just don't understand the way the Preferences are working and also never worked with UiLists.

$\endgroup$
5
  • $\begingroup$ i would recommend provide what you have (so we don't get the impression that you only search someone who does the work for you) and then we can improve your code and don't have to write everything on our own. $\endgroup$
    – Chris
    Commented Apr 19 at 7:55
  • $\begingroup$ Hello. You want to use a CollectionProperty rather than a PointerProperty $\endgroup$
    – Gorgious
    Commented Apr 19 at 8:28
  • $\begingroup$ If I would have the code, I would not ask for help. I don't understand how I can reference other classes from the preference class, so that it gets saved in the preferences and not in the actual file, like all other properties do. I also don't understand how to generate a UIList when I don't know it's length. (I read in a file and store the content in a list.) I'm not a programmer so sometimes I'm struggling to understand some concepts behind the Blender API. I also try to analyse the asset_browser_utility from you Gorgious but it's quite complicated for me. You are using PointerProperties. $\endgroup$
    – Steve
    Commented Apr 19 at 8:38
  • $\begingroup$ I also look at this example: gist.github.com/p2or/d6dfd47366b2f14816f57d2067dcb6a9 where I could replace the ADD operator with my operator which reads in the file. But in this example the content is coming from the scene. I have no scene as I'm dealing with the preferences. I have some properties in my preferences but these are all defined in the preference class. I make a PropertyGroup with the variables for each line in the file (FileName, ModDate...). I can instance that PropertyGroup and add an new instance for each line of the file. But how do I connect it to a UIList & Prefs? $\endgroup$
    – Steve
    Commented Apr 19 at 8:57
  • $\begingroup$ I updated my initial question with some code I tried. But the UiList is not working as it can't find the property. $\endgroup$
    – Steve
    Commented Apr 19 at 9:43

1 Answer 1

1
$\begingroup$

You don't define lib_list in the init as bpy.types.Preferences.lib_list = bpy.props.CollectionProperty(type=Library_List)

Here is the correct way.

import bpy


class CUSTOM_UL_items(bpy.types.UIList):
    def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
        split = layout.split(factor=0.3)
        split.label(text=item.lib_name)
        split.label(text=str(item.lib_last_mod))


class CUSTOM_PG_library_list(bpy.types.PropertyGroup):
    lib_name: bpy.props.StringProperty(name="lib_name")
    lib_last_mod: bpy.props.IntProperty(name="lib_last_mod")


class AddonPreference(bpy.types.AddonPreferences):
    bl_idname = __package__

    lib_list: bpy.props.CollectionProperty(type=CUSTOM_PG_library_list)
    lib_list_index: bpy.props.IntProperty()

    def draw(self, context):
        layout = self.layout

        layout.template_list("CUSTOM_UL_items", "", self, "lib_list", self, "lib_list_index", rows=2)


classes = (
    CUSTOM_UL_items,
    CUSTOM_PG_library_list,
    AddonPreference,
)

register, unregister = bpy.utils.register_classes_factory(classes)
$\endgroup$
4
  • $\begingroup$ Thanks Karan for the Answer. Unfortunately I can't make it work in my Add-On. I updated my Question with the error I get. $\endgroup$
    – Steve
    Commented Apr 21 at 11:55
  • $\begingroup$ you need to register CUSTOM_PG_library_list $\endgroup$
    – Karan
    Commented Apr 21 at 14:59
  • $\begingroup$ use this addon-template $\endgroup$
    – Karan
    Commented Apr 21 at 15:09
  • 1
    $\begingroup$ It was registered but I made the mistake that I declared CUSTOM_PG_library_list after I declared PREF_PT_Preferences. In the register classes (in init.py) I also added CUSTOM_PG_library_list behind all others which was another mistake. Now I moved CUSTOM_PG_library_list in front both in the definition as well as in the register list and now it works. I was not aware of this order as in the rest of my code the order did not made a difference. Apparently, for the Preferences class it matters a lot. Many thanks for your help! $\endgroup$
    – Steve
    Commented Apr 21 at 17:42

You must log in to answer this question.

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