Blender python: Add-on template with input on the tool shelf left

I made a python code template for Blender add-on.
The primary purpose of the template is to make a value input box in the tool shelf on the left of 3D view.

addon-template_input1

This seemed to be easy at first, but there are some tips for that.
I am going to explain how to do it, with fractions of code that omit unnecessary code.
And at the end, I will show the entire add-on template.
The Gist of the template is blender_addon_template_toolshelf-input1.py .

 

register():

Input properties are defined in a sub class of “bpy.types.Operator”.

Usually, input properties are assigned to a variable, for example “float_input”, in a sub class of “bpy.types.Operator” like below.

class CreateObject(bpy.types.Operator):
        float_input = bpy.props.FloatProperty(
        name = "Float",
        description = "Set float",
        default = 2.0,
        min = 1.0,
        max = 10.0
    )

But if you want to make an input property on the tool shelf,  you should assign it to “bpy.types.Scene.float_input” in register().
The reason for the assignment is that “bpy.types.Scene.~” can store the data and can be accessed in other classes which relates with menu UI settings.
The register() works when the add-on is activated, which means that “bpy.types.Scene.float_input” is made when add-on is activated.

def register():
    bpy.utils.register_module(__name__)
    bpy.types.Scene.float_input = bpy.props.FloatProperty(
        name = "Float",
        description = "Set float",
        default = 2.0,
        min = 1.0,
        max = 10.0
    )

 

unregister():

The “bpy.types.Scene.float_input” should be deleted when the add-on is deactivated.
So you should delete it in unregister()

def unregister():
    del bpy.types.Scene.float_input
    bpy.utils.unregister_module(__name__)

 

execute(self, context):

In “execute(self. context)” in the subclass of bpy.types.Operator, the input value of “bpy.types.Scene.float_input” can be accessed by “context.scene.float_input”.

    def execute(self, context):
        bpy.ops.mesh.primitive_ico_sphere_add()
        active_obj = context.active_object
        # Input before execute on the left tool shelf.
        active_obj.scale = active_obj.scale * context.scene.float_input
        return {'FINISHED'}

 

class CreateObjectPanel(bpy.types.Panel):

A subclass of “bpy.types.Panel” takes responsibility for menu setting.

You can make a menu in the tool shelf by defining variables as ‘bl_space_type = “VIEW_3D”‘, ‘bl_region_type = “TOOLS”‘,  ‘bl_category = “Tools”‘.
And in “draw(self, context)”, you can make an input box which references to “bpy.types.Scene.float_input” by ‘self.layout.row().prop(context.scene, “float_input”)’.

class CreateObjectPanel(bpy.types.Panel):
    bl_label = "CREATE Object"
    bl_idname = "create_object" # class ID.
    bl_space_type = "VIEW_3D"
    bl_region_type = "TOOLS" # Put the menu on the left tool shelf.
    bl_category = "Tools" # Tab name of the tool shelf.
    bl_context = (("objectmode"))
    
    # Menu and input.
    def draw(self, context):
         layout = self.layout
         row = layout.row()
         row.label("Row menu")

         # Input button for bpy.types.Scene.float_input.
         row.prop(context.scene, "float_input")
         # Execute button for CreateObject.
         layout.operator(CreateObject.bl_idname)

 

The entire code for the add-on template:

import bpy

# Meta information.
bl_info = {
    "name": "Addon-template1: Add IcoSphere",
    "author": "Gappy",
    "version": (1, 0),
    "blender": (2, 75, 0),
    "location": "Object > Ball",
    "description": "Add IcoSphere",
    "warning": "",
    "support": "TESTING",
    "wiki_url": "",
    "tracker_url": "",
    "category": "Object"
}


# Operation.
class CreateObject(bpy.types.Operator):

    bl_idname = "object.create_object" # Access the class by bpy.ops.object.create_object.
    bl_label = "Ball"
    bl_description = "Add IcoSphere"
    bl_options = {'REGISTER', 'UNDO'}
    
    # Input property-------------------
    # xyz vector values.:
    float_vector_input = bpy.props.FloatVectorProperty(
        name = "Float Vector",
        description = "Set float vector",
        default = <sup class='footnote'><a href='#fn-2987-1' id='fnref-2987-1' onclick='return fdfootnote_show(2987)'>1</a></sup>,
        min = 1.0,
        max = 10.0,
        subtype = &quot;XYZ&quot;
    )
    # File selection.:
    string_input = bpy.props.StringProperty(
        name = &quot;String&quot;,
        description = &quot;Set string&quot;,
        default = &quot;testfile.csv&quot;,
        subtype = &quot;FILE_PATH&quot; # Set as file selection.
    )
    # Select box.
    select_box = bpy.props.EnumProperty(
        name = &quot;Select box&quot;,
        description = &quot;Set select box&quot;,
        # [(ID, name, description)]
        items = [('3D_CURSOR', &quot;3D cursor&quot;, &quot;Locate on 3D cursor&quot;),
                ('ORIGIN', &quot;origin&quot;, &quot;Locate on origin&quot;)]
    )
    # A check box.
    check_box = bpy.props.BoolProperty(
        name = &quot;Check box&quot;,
        description = &quot;Set check box&quot;
    )
    # xyz check box.
    xyz_check_box = bpy.props.BoolVectorProperty(
        name = &quot;XYZ check box&quot;,
        description = &quot;Set XYZ check box&quot;,
        default = [True, True, False],
        subtype = &quot;XYZ&quot; # Set xyz check box
    )
    # -----------------------------------------

    # Execute function.
    def execute(self, context):
        bpy.ops.mesh.primitive_ico_sphere_add()
        active_obj = context.active_object
        # Input before execute on the left tool shelf.
        active_obj.scale = active_obj.scale * context.scene.float_input
        # Input after execute on the left below panel.
        active_obj.location = active_obj.location + self.float_vector_input # 
        print(&quot;Added ball in 3D view.&quot;)
        return {'FINISHED'}

# Menu setting.
class CreateObjectPanel(bpy.types.Panel):
    bl_label = &quot;CREATE Object&quot;
    bl_idname = &quot;create_object&quot; # class ID.
    bl_space_type = &quot;VIEW_3D&quot;
    bl_region_type = &quot;TOOLS&quot; # Put the menu on the left tool shelf.
    bl_category = &quot;Tools&quot; # Tab name of the tool shelf.
    bl_context = ((&quot;objectmode&quot;))
    
    # Menu and input:
    def draw(self, context):
         obj = context.object
         scene = context.scene
         
         layout = self.layout
         
         row = layout.row()
         row.label(&quot;Row menu&quot;)
         row.prop(scene, &quot;float_input&quot;) # Input button for bpy.types.Scene.float_input.
         
         box = layout.box()
         box.label(&quot;Box menu&quot;)
         box.operator(&quot;object.select_all&quot;).action = 'TOGGLE' # Select all button.
         box.operator(&quot;object.select_random&quot;) # Random select button.
         # Execute button for CreateObject.
         layout.operator(CreateObject.bl_idname)

def register():
    bpy.utils.register_module(__name__)
    # bpy.types.Scene~ = To show the input in the left tool shelf, store &quot;bpy.props.~&quot;.
    #   In draw() in the subclass of Panel, access the input value by &quot;context.scene&quot;.
    #   In execute() in the class, access the input value by &quot;context.scene.float_input&quot;.
    bpy.types.Scene.float_input = bpy.props.FloatProperty(
        name = &quot;Float&quot;,
        description = &quot;Set float&quot;,
        default = 2.0,
        min = 1.0,
        max = 10.0
    )
    print(&quot;This add-on was activated.&quot;)

def unregister():
    del bpy.types.Scene.float_input
    bpy.utils.unregister_module(__name__)
    print(&quot;This add-on was deactivated.&quot;)

if __name__ == &quot;__main__&quot;:
    register()

If you get a problem or a error using the code, please comment.

  1. 0, 3.2, 4.4

Leave a Reply