[Blender Python] Organiser les données de propriétés personnalisées dans template_list () de la disposition de l'interface utilisateur

Qu'est-ce que template_list ()?

2016-05-01_20h40_39.png

échantillon

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()

Copiez-le et collez-le dans l'éditeur de texte de Blender et exécutez-le.

Résultat d'exécution

2016-05-08_13h43_27.png Vous pouvez ajouter et supprimer des données à partir des boutons + et-. Déplacez l'élément sélectionné avec les boutons haut et bas. Vous pouvez tout supprimer avec le bouton Tout effacer.

Commentaire

Un opérateur distinct est préparé pour ajouter et supprimer des données, et placé à côté de celui-ci afin qu'il ait la même apparence que les autres panneaux. Lors de son utilisation, il est préférable de placer le bouton de suppression dans un endroit éloigné.

Vous devez éviter vous-même les noms en double.

Il semble que le contenu de la liste soit affiché dans draw_item () de la classe MY_UL_test_group_list. Vous pouvez l'afficher en remplaçant "nom" par "int_val".

L'endroit où vous pouvez le modifier directement en double-cliquant est le même.

finalement

Je ne pense pas avoir beaucoup de chance d'utiliser template_list (), mais j'en avais un peu besoin, alors j'ai essayé de savoir comment l'utiliser.

Recommended Posts

[Blender Python] Organiser les données de propriétés personnalisées dans template_list () de la disposition de l'interface utilisateur
Visualisation en temps réel des données thermographiques AMG8833 en Python
L'histoire de la lecture des données HSPICE en Python
Environnement enregistré pour l'analyse des données avec Python
Traitement pleine largeur et demi-largeur des données CSV en Python
Automatisation de l'interface utilisateur avec Python
Ne pas être conscient du contenu des données en python
Liste du code Python utilisé dans l'analyse de Big Data
Utilisons les données ouvertes de "Mamebus" en Python
Tri personnalisé en Python3
Essayez de gratter les données COVID-19 Tokyo avec Python
Résumé de base des opérations de données dans Python Pandas - Deuxième moitié: agrégation de données
[Homologie] Comptez le nombre de trous dans les données avec Python
[Blender x Python] Organisons une grande quantité de Susanne proprement !!
Comparaison de la gestion des trames de données en Python (pandas), R, Pig
Afficher les données UTM-30LX en Python
Jugement d'équivalence d'objet en Python
UI Automation Partie 2 en Python
API Blender Python dans Houdini (Python 3)
Implémentation du tri rapide en Python
Générez 8 * 8 (64) cubes avec Blender Python
Une analyse simple des données de Bitcoin fournie par CoinMetrics en Python
Dessinez des ondes sinusoïdales avec Blender Python
Obtenez des données LeapMotion en Python.
Lire les données des tampons de protocole avec Python3
Obtenir des données de Quandl en Python
Diviser timedelta dans la série Python 2.7
Échappement automatique des paramètres MySQL en python
Gestion des fichiers JSON en Python
Implémentation du jeu de vie en Python
Hashing de données en R et Python
La loi des nombres en python
Implémentation du tri original en Python
Brouillage réversible d'entiers en Python
Démarrez avec Python avec Blender
Modèle d'espace d'états personnalisé en Python
Comment envoyer une image visualisée des données créées en Python à Typetalk
Mémo de l'opération de position de pixel pour les données d'image avec Python (numpy, cv2)
Encodage et décodage JSON avec python
Jugement d'équivalence d'objet en Python
Lecture de code de faker, une bibliothèque qui génère des données de test en Python
Python: prétraitement en machine learning: gestion des données manquantes / aberrantes / déséquilibrées
Obtenez la clé pour la migration de la deuxième couche de données JSON avec python