Skip to content

Instantly share code, notes, and snippets.

@CGArtPython
Created November 18, 2024 06:41
Show Gist options
  • Save CGArtPython/38986ef93f03d14cdeddefd8c4916bd3 to your computer and use it in GitHub Desktop.
Save CGArtPython/38986ef93f03d14cdeddefd8c4916bd3 to your computer and use it in GitHub Desktop.
[Blender Python] basic UI list pane (explanation https://www.skool.com/cgpython/ui-guide?p=47cf4527)
import random
import bpy
# Define a custom property group for our list items
class MyItem(bpy.types.PropertyGroup):
name: bpy.props.StringProperty(name="Item Name", default="New Item")
number: bpy.props.IntProperty(name="Item Number", default=0)
class AddItemOperator(bpy.types.Operator):
"""Operator to add an item to the collection"""
bl_idname = "my_list.add_item"
bl_label = "Add Item"
def execute(self, context):
item = context.scene.my_collection.add()
item.name = f"Item {len(context.scene.my_collection)}"
item.number = random.randint(0, 100)
return {'FINISHED'}
class RemoveItemOperator(bpy.types.Operator):
"""Operator to remove an item from the collection"""
bl_idname = "my_list.remove_item"
bl_label = "Remove Item"
index: bpy.props.IntProperty()
def execute(self, context):
collection = context.scene.my_collection
if 0 <= self.index < len(collection):
collection.remove(self.index)
return {'FINISHED'}
class MY_UL_List(bpy.types.UIList):
"""UIList for displaying items"""
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
if self.layout_type in {'DEFAULT', 'COMPACT'}:
row = layout.row(align=True)
row.prop(item, "name", text="", emboss=False)
row.prop(item, "number", text="", emboss=False)
elif self.layout_type == 'GRID':
layout.label(text="")
# Create a panel to display the list and buttons
class MY_PT_Panel(bpy.types.Panel):
"""Panel in the Scene Props"""
bl_label = "My Custom List Panel 33"
bl_idname = "MY_PT_panel"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = 'scene'
def draw(self, context):
layout = self.layout
scene = context.scene
# Draw the list
layout.template_list("MY_UL_List", "", scene, "my_collection", scene, "my_collection_index")
# Draw the add and remove buttons
row = layout.row()
row.operator("my_list.add_item", icon='ADD', text="Add")
remove_op = row.operator("my_list.remove_item", icon='REMOVE', text="Remove")
remove_op.index = scene.my_collection_index
# Register the custom property, classes, and operators
classes = [
MyItem,
AddItemOperator,
RemoveItemOperator,
MY_UL_List,
MY_PT_Panel
]
def register():
for cls in classes:
bpy.utils.register_class(cls)
bpy.types.Scene.my_collection = bpy.props.CollectionProperty(type=MyItem)
bpy.types.Scene.my_collection_index = bpy.props.IntProperty()
def unregister():
for cls in reversed(classes):
bpy.utils.unregister_class(cls)
del bpy.types.Scene.my_collection
del bpy.types.Scene.my_collection_index
if __name__ == "__main__":
register()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment