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.
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 = "XYZ" ) # File selection.: string_input = bpy.props.StringProperty( name = "String", description = "Set string", default = "testfile.csv", subtype = "FILE_PATH" # Set as file selection. ) # Select box. select_box = bpy.props.EnumProperty( name = "Select box", description = "Set select box", # [(ID, name, description)] items = [('3D_CURSOR', "3D cursor", "Locate on 3D cursor"), ('ORIGIN', "origin", "Locate on origin")] ) # A check box. check_box = bpy.props.BoolProperty( name = "Check box", description = "Set check box" ) # xyz check box. xyz_check_box = bpy.props.BoolVectorProperty( name = "XYZ check box", description = "Set XYZ check box", default = [True, True, False], subtype = "XYZ" # 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("Added ball in 3D view.") return {'FINISHED'} # Menu setting. 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): obj = context.object scene = context.scene layout = self.layout row = layout.row() row.label("Row menu") row.prop(scene, "float_input") # Input button for bpy.types.Scene.float_input. box = layout.box() box.label("Box menu") box.operator("object.select_all").action = 'TOGGLE' # Select all button. box.operator("object.select_random") # 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 "bpy.props.~". # In draw() in the subclass of Panel, access the input value by "context.scene". # In execute() in the class, access the input value by "context.scene.float_input". bpy.types.Scene.float_input = bpy.props.FloatProperty( name = "Float", description = "Set float", default = 2.0, min = 1.0, max = 10.0 ) print("This add-on was activated.") def unregister(): del bpy.types.Scene.float_input bpy.utils.unregister_module(__name__) print("This add-on was deactivated.") if __name__ == "__main__": register()
If you get a problem or a error using the code, please comment.
- 0, 3.2, 4.4 ↩