[EXAMPLE] String-Int-Bool-Float-Enum in Object Panel.

Hello All,

I received a PM request for creating a custom Enum property. I thought I’d just post it, for all types, here for everyone to see.

To use this script paste it into a text window and run it.
Then Select an object and activate the object context.
Scroll to the bottom of the panel to view the various types in the panel.


import bpy
from bpy.props import IntProperty, FloatProperty, StringProperty, BoolProperty, EnumProperty

def updateIntParameter(self,context):
    # This def gets called when one of the properties changes state.
    print(self.my_int)
def updateFloatParameter(self,context):
    # This def gets called when one of the properties changes state.
    print(self.my_float)
def updateBoolParameter(self,context):
    # This def gets called when one of the properties changes state.
    print(self.my_bool) 
def updateStringParameter(self,context):
    # This def gets called when one of the properties changes state.
    print(self.my_string) 
def updateEnumParameter(self,context):
    # This def gets called when one of the properties changes state.
    print(self.my_axis) 
       
class cls_IntFloatString(bpy.types.PropertyGroup):
    # The properties for this class which is referenced as an 'entry' below.
    my_bool = bpy.props.BoolProperty(name="My Boolean", description="Boolean.", update=updateBoolParameter)    
    my_int = bpy.props.IntProperty(name="My Integer", description="Integer.", default=1, min=0, max=12, update=updateIntParameter)    
    my_float = bpy.props.FloatProperty(name="My Float", description="Float.", default=1.0, min=0.000, max=18.0, step=3, precision=4, options={'ANIMATABLE'}, subtype='FACTOR', unit='NONE', update=updateFloatParameter)
    my_string = bpy.props.StringProperty(name="My String", description="Type your string here.", update=updateStringParameter)
    axis_types = [
                ("0","None","None"),
                ("1","X","X"),
                ("2","Y","Y"),
                ("3","Z","Z"),
                ("4","XY","XY"),
                ("5","YZ","YZ"),
                ("6","XZ","XZ"),
                ("7","XYZ","XYZ"),
                ("8","ZXY","ZXY"),
                ("9","XZY","XZY"),
                ]
    my_axis= EnumProperty(name="My Axis", description="The axis that will be relayed to the target.", default="7", items=axis_types, update=updateEnumParameter)
    
bpy.utils.register_class(cls_IntFloatString)

# Add these properties to every object in the entire Blender system (muha-haa!!)
bpy.types.Object.My_List_Index = bpy.props.IntProperty(min= 0,default= 0)
bpy.types.Object.My_List = bpy.props.CollectionProperty(type=cls_IntFloatString)

class IntFloatStringPanel(bpy.types.Panel):
    bl_label = "Int Float String"
    bl_idname = "OBJECT_PT_hello"
    bl_space_type = "PROPERTIES"
    bl_region_type = "WINDOW"
    bl_context = "object"

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

        obj = context.object
        l = len(obj.My_List)
        if l > 0:
            entry = obj.My_List[obj.My_List_Index]
            
            box1 = layout.box() 
            row1 = box1.row()
            row1.label(" Label:", icon='INFO')
            
            # Display properties for each type.
            box1.prop(entry, "my_string", icon='OBJECT_DATAMODE')
            box1.prop(entry, "my_int")
            box1.prop(entry, "my_bool")
            box1.prop(entry, "my_float")
            box1.prop(entry, 'my_axis')
        else:
            # This list is zero length, so let's add one.
            collection = obj.My_List
            collection.add()


def register():
    bpy.utils.register_class(IntFloatStringPanel)


def unregister():
    bpy.utils.unregister_class(IntFloatStringPanel)


if __name__ == "__main__":
    register()

Attachments


This is exactly kind of information I expect. Simple, straight to the point and works (and if the script does not work in the future, we can always track back and update it).

Cheers ATOM! Will give it a try now. I will refer to this info for my blog post.

Would it be possible to put this in the Toolshelf or Properties panel? Which part of script to modify, I wonder.

Anyhow, I will study this script first…

@enzyme69,

From Atom’s code above, this part (the top) tells the script which properties to create.

import bpy
from bpy.props import IntProperty, FloatProperty, StringProperty, BoolProperty, EnumProperty

def updateIntParameter(self,context):
    # This def gets called when one of the properties changes state.
    print(self.my_int)
def updateFloatParameter(self,context):
    # This def gets called when one of the properties changes state.
    print(self.my_float)
def updateBoolParameter(self,context):
    # This def gets called when one of the properties changes state.
    print(self.my_bool) 
def updateStringParameter(self,context):
    # This def gets called when one of the properties changes state.
    print(self.my_string) 
def updateEnumParameter(self,context):
    # This def gets called when one of the properties changes state.
    print(self.my_axis) 
       
class cls_IntFloatString(bpy.types.PropertyGroup):
    # The properties for this class which is referenced as an 'entry' below.
    my_bool = bpy.props.BoolProperty(name="My Boolean", description="Boolean.", update=updateBoolParameter)    
    my_int = bpy.props.IntProperty(name="My Integer", description="Integer.", default=1, min=0, max=12, update=updateIntParameter)    
    my_float = bpy.props.FloatProperty(name="My Float", description="Float.", default=1.0, min=0.000, max=18.0, step=3, precision=4, options={'ANIMATABLE'}, subtype='FACTOR', unit='NONE', update=updateFloatParameter)
    my_string = bpy.props.StringProperty(name="My String", description="Type your string here.", update=updateStringParameter)
    axis_types = [
                ("0","None","None"),
                ("1","X","X"),
                ("2","Y","Y"),
                ("3","Z","Z"),
                ("4","XY","XY"),
                ("5","YZ","YZ"),
                ("6","XZ","XZ"),
                ("7","XYZ","XYZ"),
                ("8","ZXY","ZXY"),
                ("9","XZY","XZY"),
                ]
    my_axis= EnumProperty(name="My Axis", description="The axis that will be relayed to the target.", default="7", items=axis_types, update=updateEnumParameter)
    
bpy.utils.register_class(cls_IntFloatString)

# Add these properties to every object in the entire Blender system (muha-haa!!)
bpy.types.Object.My_List_Index = bpy.props.IntProperty(min= 0,default= 0)
bpy.types.Object.My_List = bpy.props.CollectionProperty(type=cls_IntFloatString)

This part creates a panel, with inputs using the properties from the previous part. To change where this panel goes, look up bl_space_type & bl_region_type in the api. (this is bl_space_type)

class IntFloatStringPanel(bpy.types.Panel):
    bl_label = "Int Float String"
    bl_idname = "OBJECT_PT_hello"
    bl_space_type = "PROPERTIES"
    bl_region_type = "WINDOW"
    bl_context = "object"

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

        obj = context.object
        l = len(obj.My_List)
        if l > 0:
            entry = obj.My_List[obj.My_List_Index]
            
            box1 = layout.box() 
            row1 = box1.row()
            row1.label(" Label:", icon='INFO')
            
            # Display properties for each type.
            box1.prop(entry, "my_string", icon='OBJECT_DATAMODE')
            box1.prop(entry, "my_int")
            box1.prop(entry, "my_bool")
            box1.prop(entry, "my_float")
            box1.prop(entry, 'my_axis')
        else:
            # This list is zero length, so let's add one.
            collection = obj.My_List
            collection.add()


def register():
    bpy.utils.register_class(IntFloatStringPanel)


def unregister():
    bpy.utils.unregister_class(IntFloatStringPanel)


if __name__ == "__main__":
    register()

try to have this added to the sticky may be

thanks

@crazycourier
you could also sent these to Valter so he can add these to the code snippets in wiki !

nice examples

happy blendering

@crazycourier
thanks for additional informations! I’ll have to study this properly…!

btw, your bTrace collaboration add-on with liero rocks. would like to see it developed further in the future. I wrote a lot about bTrace on my blog.

@ATOM
cheers again for showing this. code tends to look intimidating very quickly, but not so much when dissected and understood.

Thanks! Really interesting.

@crazycourier: what theme is that? Care to share it ?

@enzyme,
I have been working on a new tool for bTrace which I should be releasing soon. I’ll keep adding to it, but we’ll save that conversation for another thread.

@gianmichele,
The theme came with my blender build, it’s elsyiun.xml. If you don’t have it let me know and I’ll send it to you.

hello, Atom, I am trying to make a combined menu for the zmj,s addons, and im trying to use a enum property but it actually doesnt work (im not a programmer, just a user, so the easy things in programming are very difficult for me) could you look at my code and help me with it? Here it is:
import bpy
from bpy.props import *
from bpy.props import EnumProperty

def updateEnumParameter(self,context):
# This def gets called when one of the properties changes state.
print(self.my_axis)

class myMenuProperty(bpy.types.PropertyGroup):
menu_types = [
(“0”,“ProjArb”,“project arbitrary”),
(“1”,“VertAl”,“vertex align”),
(“2”,“VertSl”,“vertex slide”),
(“3”,“ArbRot”,“arbitrary rotate”),
(“4”,“MirArb”,“mirror arbitrary”),
(“5”,“others”,“others”),
]
my_menu= EnumProperty(name=“My Axis”, description=“The axis that will be relayed to the target.”, default=“0”, items=my_menu, update=updateEnumParameter)

class MyZMJToolsPanel(bpy.types.Panel):
bl_label = “MY ZMJ TOOLS PANEL”
bl_space_type = “VIEW_3D”
bl_region_type = ‘TOOLS’

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

    obj = context.object
    
    
    
    layout.prop('my_axis', expand=True)

    if my_menu =="0":
        row = layout.row()
        row.label('HERE MUST BE PROJECT ARBITRARY BUTTONS:')
          

    if my_menu =="1":
        row = layout.row()
        row.label('HERE MUST BE VERTEX ALIGN BUTTONS:')


    if my_menu =="2":
        row = layout.row()
        row.label('HERE MUST BE VERTEX SLIDE BUTTONS:')


    if my_menu =="3":
        row = layout.row()
        row.label('HERE MUST ARBITRARY ROTATE BUTTONS:')


    if my_menu =="4":
        row = layout.row()
        row.label('HERE MUST BE MIRROR ARBITRARY BUTTONS:')


    if my_menu =="5":
        row = layout.row()
        row.label('HERE MUST BE OTHERS ZMJ ADDONS BUTTONS:')

oh, I almost forgot, can you make it to be associated with the scene, rather than the object, I want to re-use it later for another menus that are not particularly object related?!Thank in advance!

Oops double post.

Hi spirit,

to wrap code use [xcode] code here [/xcode] … code not xcode. There is a no markup flag but i can never remember it.


import bpy
from bpy.props import *
from bpy.props import EnumProperty

def updateEnumParameter(self,context):
    # This def gets called when one of the properties changes state.
    print(self.my_axis) 


menu_types = [
    ("0","ProjArb","project arbitrary"),
    ("1","VertAl","vertex align"),
    ("2","VertSl","vertex slide"),
    ("3","ArbRot","arbitrary rotate"),
    ("4","MirArb","mirror arbitrary"),
    ("5","others","others"),
    ]
bpy.types.Scene.my_axis = EnumProperty(name="My Axis", description="The axis that will be relayed to the target.", default="0", items=menu_types, update=updateEnumParameter)


class MyZMJToolsPanel(bpy.types.Panel):
    bl_label = "MY ZMJ TOOLS PANEL"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'TOOLS'

    def draw(self, context):
        layout = self.layout
        
        obj = context.object
        scene = context.scene
        
        
        layout.prop(scene, "my_axis", expand=True)
        my_menu = scene.my_axis
        
        if my_menu == '0':
            row = layout.row()
            row.label('HERE MUST BE PROJECT ARBITRARY BUTTONS:')
            
        
        elif my_menu == '1':
            row = layout.row()
            row.label('HERE MUST BE VERTEX ALIGN BUTTONS:')
        
        
        elif my_menu == '2':
            row = layout.row()
            row.label('HERE MUST BE VERTEX SLIDE BUTTONS:')
        
        
        elif my_menu == '3':
            row = layout.row()
            row.label('HERE MUST ARBITRARY ROTATE BUTTONS:')
        
        
        elif my_menu == '4':
            row = layout.row()
            row.label('HERE MUST BE MIRROR ARBITRARY BUTTONS:')
        
        
        elif my_menu == '5':
            row = layout.row()
            row.label('HERE MUST BE OTHERS ZMJ ADDONS BUTTONS:')
            
            
def register():
    bpy.utils.register_class(MyZMJToolsPanel)
    
#initialise

bpy.context.scene.my_axis = '0'
register()

thanks very much - this resolves my problem!

thank you too, Batfinger, looks very clean, I will try it for sure! Cheers!

Thanks, batfinger, it works for me perfect - this is exactly what I wanted! Although, RickyBlender wrote me that it gives him an error message in Bmesh build!

i tried with Bmesh 917
and got an error on my menu var

so i added in functions the global my menu
and now seems to work ok

also need to transfert the menu var to my menu in first function with

my_menu=self.my_axis

also need to defined my menu in main
so now working ok

i like this one cause the rows of buttons
is almost like a multi choice toggle box
you clik on one and it does something
and only one box can be activated

so interesting way of using it !

thanks

This example you’ve posted is wonderful!
A quick question - how do you display “example results” that don’t commit unless you finish editing values?

Hi, Atom, I need to make the enumproperty elements instead with words, something like that for example:

menu_types = [
(“0”,“ProjArb”,“project arbitrary”,icon=“TEXTURE”), …(obviously this dont work)

I looked in your another thread that you send me a link but I need to do it in such a way that i preserve the enumproperties positive sides - I mean, it must look exactly like the enumproperty in the header of the properties window - the one that you switch between constraints panel, modifiers panel, materials panel, textures panel, etc.,you know, only icons without text!

So, I wonder, do you know a method for that?

so much good information in this thread. I can only lurk and read for now because my questions would cause thunderstorms with my newbness haha. Good stuff!