I need to create a list-like widget. I have looked into the Blender default panels sources, but I find them hard to dissect, and would like a more straightforward example.
Either of those two types of widgets would be fine for my purpose. Basically I need to be able to re-popoulate the list with some filenames, on a button click, and then be able to tell which item on the list is selected. So my guess is that I would need to dynamically generate a property (enum?) from which I would be able to get the current list selection?
Could anyone help me with the code (or explanation) for how would the property / panel combo look like in this case, or point me to some resources that deal with such issue.
i think i have an old example for collection
but not working anymore can you help to make it work again!
import bpy
## class where the custom properties for the Collection will be nested
## (each entry of the collection will derive its Properties from this Class
## and can hold own values for each property)
class PropertyGroup(bpy.types.IDPropertyGroup):
pass
bpy.types.Object.mychosenObject = bpy.props.StringProperty()
## create CollectionProperty and link it to the property class
bpy.types.Object.myCollection = bpy.props.CollectionProperty(type = PropertyGroup)
bpy.types.Object.myCollection_index = bpy.props.IntProperty(min = -1, default = -1)
## create Properties for the collection entries:
PropertyGroup.mystring = bpy.props.StringProperty()
PropertyGroup.mybool = bpy.props.BoolProperty(default = False)
## create operator to add or remove entries to/from the Collection
class OBJECT_OT_add_remove_Collection_Items(bpy.types.Operator):
bl_label = "Add or Remove"
bl_idname = "collection.add_remove"
add = bpy.props.BoolProperty(default = True)
def invoke(self, context, event):
add = self.add
obj = context.object
collection = obj.myCollection
if add:
collection.add() # This add at the end of the collection list
else:
index = obj.myCollection_index
collection.remove(index) # This remove on item in the collection list function of index value
class OBJECT_PT_ObjectSelecting(bpy.types.Panel):
bl_label = "Object Selecting"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "object"
def draw(self, context):
obj = context.object
layout = self.layout
##show collection in Panel:
row = layout.row()
row.template_list(obj, "myCollection", obj, "myCollection_index") # This show list for the collection
##show add/remove Operator
col = row.column(align=True)
col.operator("collection.add_remove", icon="ZOOMIN", text="") # This show a plus sign button
col.operator("collection.add_remove", icon="ZOOMOUT", text="").add = False # This show a minus sign button
##change name of Entry:
if obj.myCollection:
entry = obj.myCollection[obj.myCollection_index]
layout.prop(entry, "name")
##show self created properties of myCollection
layout.prop(entry, "mystring")
layout.prop(entry, "mybool")
### search prop to search in myCollection:
layout.prop_search(obj, "mychosenObject", obj, "myCollection")
I tried to get somewhere with that code, but I’ll need some more help.
For now I can’t even register the property group, it complains that the filelist object can’t register.
import bpy
from bpy.props import PointerProperty, CollectionProperty, StringProperty, BoolProperty, IntProperty
# to hold multiple properties that fit together
class MyPropertyGroup(bpy.types.IDPropertyGroup):
filelist = CollectionProperty([], type=StringProperty)
listindex = IntProperty(min=0, default=0)
chosen = StringProperty()
bpy.utils.register_class(MyPropertyGroup)
The reasoning behind this code is that I want to have a property group, that encapsulates all the properties of that list panel I want - ie. a collection of string properties (filenames), the number of the current list index and the value (name of file) of the currently selected item. Does this make sense?
How are collection properties properly initialized (I passed an empty list, because at this point there is no data to fill)? And especially; how are collections of properties iterated and manipulated (remove, add, etc…)
Thanks andreymi, that code works! (PropertyGroup needs to be replaced with IDPropertyGroup)
Now things are a little clearer
BTW, I don’t see a remove() method on CollectionProperty mentioned in the API (it wont let me to post links), how I’m supposed to know that remove() exists?
Traceback (most recent call last):
File “collection351611.py”, line 5, in <module>
AttributeError: ‘RNA_Types’ object has no attribute ‘IDPropertyGroup’
don’t know do you an older veison around 35161 ?
and at graphical there is only up to around 35256 !
so don’t think it’s the problem
i’ll try later on to get a new vresion today
but may be you should update to a lter version to get the same problem
34855 is a little old by now
Does anybody know how do I connect an enum button set to some operator? I know how to show enum set like a property, but I want that an operator is triggered each time the user choses some option. Like for example in the material buttons, different previews are triggered depending on your choice:
RickyBlender, I have no clue why it doesn’t work for you…
These are events, and these we are waiting for the developpers to implement. It is in the TO DO list and Ton thinks in a month probably they will start with that. It is very necessary because a lot of former scripts can’t be ported until events are programmed.
ok here is the version i tested in 35161
and get no error s and no panel
may be somone can test this and tell me if you get same results
import bpy
## class where the custom properties for the Collection will be nested
## (each entry of the collection will derive its Properties from this Class
## and can hold own values for each property)
class PropertyGroup(bpy.types.PropertyGroup):
pass
bpy.utils.register_class(PropertyGroup)
bpy.types.Object.mychosenObject = bpy.props.StringProperty()
## create CollectionProperty and link it to the property class
bpy.types.Object.myCollection = bpy.props.CollectionProperty(type = PropertyGroup)
bpy.types.Object.myCollection_index = bpy.props.IntProperty(min = -1, default = -1)
## create Properties for the collection entries:
PropertyGroup.mystring = bpy.props.StringProperty()
PropertyGroup.mybool = bpy.props.BoolProperty(default = False)
## create operator to add or remove entries to/from the Collection
class OBJECT_OT_add_remove_Collection_Items(bpy.types.Operator):
bl_label = "Add or Remove"
bl_idname = "collection.add_remove"
add = bpy.props.BoolProperty(default = True)
def invoke(self, context, event):
add = self.add
obj = context.object
collection = obj.myCollection
if add:
collection.add() # This add at the end of the collection list
else:
index = obj.myCollection_index
collection.remove(index) # This remove on item in the collection list function of index value
class OBJECT_PT_ObjectSelecting(bpy.types.Panel):
bl_label = "Object Selecting"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "object"
def draw(self, context):
obj = context.object
layout = self.layout
##show collection in Panel:
row = layout.row()
row.template_list(obj, "myCollection", obj, "myCollection_index") # This show list for the collection
##show add/remove Operator
col = row.column(align=True)
col.operator("collection.add_remove", icon="ZOOMIN", text="") # This show a plus sign button
col.operator("collection.add_remove", icon="ZOOMOUT", text="").add = False # This show a minus sign button
##change name of Entry:
if obj.myCollection:
entry = obj.myCollection[obj.myCollection_index]
layout.prop(entry, "name")
##show self created properties of myCollection
layout.prop(entry, "mystring")
layout.prop(entry, "mybool")
### search prop to search in myCollection:
layout.prop_search(obj, "mychosenObject", obj, "myCollection")
bpy.utils.register_class(OBJECT_PT_ObjectSelecting)
bpy.utils.register_class(OBJECT_OT_add_remove_Collection_Items)
#bpy.utils.register_class(PropertyGroup)
location:<unknown location>:-1
TypeError: calling class function: Function.result expected a string enum or a
et of strings in (‘RUNNING_MODAL’, ‘CANCELLED’, ‘FINISHED’, ‘PASS_THROUGH’), no
NoneType
location:<unknown location>:-1