test_template_list.py
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# Blender2.77a
import bpy
def creat_not_jyuufuku_name(name, name_set, num):
new_name = ""
if '.' in name:
split_name = name.split('.')
if split_name[-1].isdigit():
new_name = ".".join(split_name[0:-1]) + ".{:03d}".format(num)
else:
if split_name[-1] == "":
new_name = name + "{:03d}".format(num)
else:
new_name = ".".join(split_name) + ".{:03d}".format(num)
else:
new_name = name + ".{:03d}".format(num)
if new_name in name_set:
return creat_not_jyuufuku_name(new_name, name_set, num+1)
return new_name
def get_my_string(self):
return self["name"]
def set_my_string(self, value):
self["name"] = value
tl = bpy.context.window_manager.test_ui_list.test_list
if len(tl) > 1:
s = set()
result = [x.name for x in tl if x.name in s or s.add(x.name)]
if len(result):
number = 1
self["name"] = creat_not_jyuufuku_name(value, s, 1)
class MyTestGroup(bpy.types.PropertyGroup):
name = bpy.props.StringProperty(get=get_my_string, set=set_my_string)
int_val = bpy.props.IntProperty()
bpy.utils.register_class(MyTestGroup)
class MyCollectionProperty(bpy.types.PropertyGroup):
active_index = bpy.props.IntProperty()
test_list = bpy.props.CollectionProperty(type=bpy.types.MyTestGroup)
def add(self):
item = self.test_list.add()
item.name = "name"
item.int_val = 10
self.active_index = len(self.test_list)-1
def remove(self):
if len(self.test_list):
self.test_list.remove(self.active_index)
if len(self.test_list)-1 < self.active_index:
self.active_index = len(self.test_list)-1
if self.active_index < 0:
self.active_index = 0
def move(self, index1, index2):
if len(self.test_list) < 2:
return
if 0 <= index1 < len(self.test_list):
if 0 <= index2 < len(self.test_list):
self.test_list.move(index1, index2)
self.active_index = index2
def clear(self):
self.test_list.clear()
class MyUIListAddItemOperator(bpy.types.Operator):
bl_idname = "view3d.my_uilist_add_item"
bl_label = "Add Item"
def execute(self, context):
context.window_manager.test_ui_list.add()
return {'FINISHED'}
class MyUIListRemoveItemOperator(bpy.types.Operator):
bl_idname = "view3d.my_uilist_remove_item"
bl_label = "Remove Item"
def execute(self, context):
context.window_manager.test_ui_list.remove()
return {'FINISHED'}
class MyUIListMoveItemOperator(bpy.types.Operator):
bl_idname = "view3d.my_uilist_move_item"
bl_label = "Move Item"
type = bpy.props.StringProperty(default='UP')
def execute(self, context):
ui_list = context.window_manager.test_ui_list
if self.type == 'UP':
ui_list.move(ui_list.active_index, ui_list.active_index-1)
elif self.type == 'DOWN':
ui_list.move(ui_list.active_index, ui_list.active_index+1)
return {'FINISHED'}
class MyUIListClearItemOperator(bpy.types.Operator):
bl_idname = "view3d.my_uilist_clear_item"
bl_label = "Clear Item"
def execute(self, context):
context.window_manager.test_ui_list.clear()
return {'FINISHED'}
class MY_UL_test_group_list(bpy.types.UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.prop(item, "name", text="", emboss=False, icon_value=icon)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon)
class UIListTestPanel(bpy.types.Panel):
bl_label = "UIList Test Panel"
bl_idname = "VIEW3D_PT_ui_list_test"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
def draw(self, context):
layout = self.layout
ui_list = context.window_manager.test_ui_list
row = layout.row()
col = row.column()
col.template_list("MY_UL_test_group_list", "", ui_list, "test_list", ui_list, "active_index", rows=1)
col = row.column(align=True)
col.operator("view3d.my_uilist_add_item", icon='ZOOMIN', text="")
col.operator("view3d.my_uilist_remove_item", icon='ZOOMOUT', text="")
col.operator("view3d.my_uilist_move_item", icon='TRIA_UP', text="").type = 'UP'
col.operator("view3d.my_uilist_move_item", icon='TRIA_DOWN', text="").type = 'DOWN'
layout.operator("view3d.my_uilist_clear_item", text="All Clear")
if len(ui_list.test_list):
row = layout.row()
row.prop(ui_list.test_list[ui_list.active_index], "name")
row = layout.row()
row.prop(ui_list.test_list[ui_list.active_index], "int_val")
def register():
bpy.utils.register_class(MyCollectionProperty)
bpy.utils.register_class(MyUIListAddItemOperator)
bpy.utils.register_class(MyUIListRemoveItemOperator)
bpy.utils.register_class(MyUIListMoveItemOperator)
bpy.utils.register_class(MyUIListClearItemOperator)
bpy.utils.register_class(MY_UL_test_group_list)
bpy.utils.register_class(UIListTestPanel)
bpy.types.WindowManager.test_ui_list = bpy.props.PointerProperty(type=MyCollectionProperty)
def unregister():
del bpy.types.WindowManager.test_ui_list
bpy.utils.unregister_class(UIListTestPanel)
bpy.utils.unregister_class(MY_UL_test_group_list)
bpy.utils.unregister_class(MyUIListAddItemOperator)
bpy.utils.unregister_class(MyUIListRemoveItemOperator)
bpy.utils.unregister_class(MyUIListMoveItemOperator)
bpy.utils.unregister_class(MyUIListClearItemOperator)
bpy.utils.unregister_class(MyCollectionProperty)
#bpy.utils.unregister_class(MyTestGroup)
if __name__ == "__main__":
register()
Kopieren Sie es, fügen Sie es in den Texteditor in Blender ein und führen Sie es aus.
Sie können Daten über die Schaltflächen + und hinzufügen und löschen. Verschieben Sie das ausgewählte Element mit den Auf- und Ab-Tasten. Sie können alle mit der Schaltfläche Alles löschen löschen.
Ein separater Operator wird zum Hinzufügen und Löschen von Daten vorbereitet und daneben platziert, sodass er wie andere Bedienfelder aussieht. Wenn Sie es tatsächlich verwenden, ist es besser, die Schaltfläche zum Entfernen an einem entfernten Ort zu platzieren.
Sie müssen doppelte Namen selbst vermeiden.
Es scheint, dass der Inhalt der Liste in draw_item () der Klasse MY_UL_test_group_list angezeigt wird. Sie können es anzeigen, indem Sie "name" in "int_val" ändern.
Der Ort, an dem Sie es direkt durch Doppelklicken ändern können, ist derselbe.
Ich glaube nicht, dass ich eine große Chance habe, template_list () zu verwenden, aber ich brauchte es ein wenig, also habe ich versucht herauszufinden, wie man es verwendet.