3
$\begingroup$

I've been writing scripts for Maya and 3Ds Max, now I'm trying to learn Python API of Blender. So I'm not a beginner in scripting for such applications, but I'm a total beginner in scripting for Blender. I'm creating an UI for my simple script. I need to have a list in the ui that will update with new items [string "name", float value] during the execution of the script.

I just want to see this in my UI:

  • name: value
  • name: value
  • [...]

I'm not exactly sure how to pass the data from the Python array to the UI list_template.All I've got is this code, that creates a UI in the panel of the scene (based on the template):

class UIScriptPanel(bpy.types.Panel):
    bl_label = "Script Panel2"
    bl_idname = "OBJECT_PT_ui_list_example"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "object"

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

        obj = bpy.types.AnyType( bpy.context.scene.my_data )

        layout.template_list("MESH_UL_scriptActionsList", "", obj, "name", obj, "id")

my_data is registered during register() with:

bpy.types.Scene.my_data = bpy.props.PointerProperty( type = MyPropertyGroup )

and MyPropertyGroup is(based on example):

class MyPropertyGroup(bpy.types.PropertyGroup):
name = bpy.props.FloatProperty(name="name")
id = bpy.props.IntProperty(name="id")

the class MESH_UL_scriptActionsList is the same as in the example. I do not know what to change in it yet..

The script runs, but the list is not displayed.

So mu question is: Is that how the creation of list for UI should look like? If yes, then why is it not working? If not, then how to create a list UI element in Python for blender that would displaye a content of list (or other data structure) from Python code?

Thank You in advance

$\endgroup$
1
  • $\begingroup$ Does this help? $\endgroup$
    – p2or
    Commented Jan 8, 2018 at 19:06

1 Answer 1

2
$\begingroup$

Ok, I've got it. But still do not fully understand.

bl_info = {
    "name": "Collection Menu",
    "author": "CoDEmanX",
    "version": (1, 0),
    "blender": (2, 65, 0),
    "location": "",
    "description": "",
    "warning": "",
    "wiki_url": "",
    "category": ""}


import bpy

coll_data = [
    ("Option A", "The first option, can be found by searching '1' as well"),
    ("Option B", "You can find this by searching for 'roflmao'"),
    ("Some text", "Some more descriptive explanation"),
    ("Blabla", "Talking stuff...")
]

class SimpleOperator(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "object.simple_operator"
    bl_label = "Simple Object Operator"

    @classmethod
    def poll(cls, context):
        return context.active_object is not None

    def execute(self, context):
        print("test")
        coll_data.append(("a", "b"))
        bpy.app.handlers.scene_update_pre.append(collhack)
        return {'FINISHED'}

class Actions_List(bpy.types.UIList):
    def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
        if self.layout_type in {'DEFAULT', 'COMPACT'}:
            # You should always start your row layout by a label (icon + text), or a non-embossed text field,
            # this will also make the row easily selectable in the list! The later also enables ctrl-click rename.
            # We use icon_value of label, as our given icon is an integer value, not an enum ID.
            # Note "data" names should never be translated!
            split = layout.split(0.3)
            split.label(item.label)
            split.label(item.description)

        elif self.layout_type in {'GRID'}:
            pass

class MyColl(bpy.types.PropertyGroup):
    #name = bpy.props.StringProperty()
    label = bpy.props.StringProperty()
    description = bpy.props.StringProperty()


class MyScriptPanel(bpy.types.Panel):
    bl_label = "MyScript Panel"
    bl_idname = "OBJECT_PT_myscript"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "scene"


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

        col = context.scene.col
        idx = context.scene.col_idx

        if idx >= len(col):
            #context.scene.col_idx = len(col) - 1
            text = "(index error)"
        else:
            text = col[idx].name

        layout.template_list("Actions_List", "", context.scene, "col", context.scene, "col_idx")
        col = layout.column(align=True)
        row = col.row(align=True)
        row.operator("object.simple_operator" , text = "All")


def collhack(scene):
    bpy.app.handlers.scene_update_pre.remove(collhack)

    try:
        scene.col.clear()
    except:
        pass

    for i, (label, description) in enumerate(coll_data, 1):
        item = scene.col.add()
        item.label = label
        item.description = description
        item.name = " ".join((str(i), label, description))



def register():
    bpy.utils.register_module(__name__)
    bpy.types.Scene.col = bpy.props.CollectionProperty(type=MyColl)
    bpy.types.Scene.col_idx = bpy.props.IntProperty(default=0)

    bpy.app.handlers.scene_update_pre.append(collhack)


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


if __name__ == "__main__":
    register()
$\endgroup$

You must log in to answer this question.

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