[PYTHON] How to create a submenu with the [Blender] plugin

In the previous Post, I explained how to make a Blender plugin with a simple sample code. This time, I will explain how to create a sub (on the tree) menu. There may be some mistakes because there is little information to create a submenu and it is the result of trial and error.

Normal menu

From the previous Post, only the part that creates the menu is excerpted.

menu_1.py


#menu
class CHoge(bpy.types.Operator):
    
    bl_idname = "uv.hoge"               #ID name
    bl_label = "Hoge Menu"              #The character string displayed in the menu
    bl_description = "Hoge Piyo"        #Description displayed in the menu
    bl_options = {'REGISTER', 'UNDO'}

    #The process that the plug-in actually performs the process
    def execute(self, context):
        return {'FINISHED'}             #Returns FINISHED on success

#Function to register a menu
def menu_func(self, context):
    self.layout.operator("uv.hoge")     #"Bl" of the class you want to register_Specify "idname"

#What happens when you install the plugin
def register():
    bpy.utils.register_module(__name__)
    bpy.types.VIEW3D_MT_uv_map.append(menu_func)

Sub (on the tree) menu

Here is a simple sample code for creating a submenu. The structure of the displayed menu is "Hoge Menu"-"Hoge Sub Menu".

submenu_1.py


#Submenu
class SubMenu(bpy.types.Operator):
    bl_idname = "uv.hoge_sub"
    bl_label = "Sub Hoge Menu"
    out_text = bpy.props.StringProperty()

    def execute(self, context):
        self.report({'INFO'}, self.out_text)
        return {'FINISHED'}

#Main menu
class Menu(bpy.types.Menu):
    bl_idname = "uv.hoge"
    bl_label = "Hoge Menu"
    bl_description = "Hoge Piyo"

    def draw(self, context):
        layout = self.layout
        #Submenu registration + output character string registration
        layout.operator(SubMenu.bl_idname).out_text = "Sub Hoge Menu"

#Register in the menu displayed when you press "U" in Edit mode (bpy).types.VIEW3D_MT_uv_map.append(menu_func)Called from)
def menu_func(self, context):
    self.layout.separator()            #Register separator in menu
    self.layout.menu(Menu.bl_idname)

#Registration
def register():
    bpy.utils.register_module(__name__)
    bpy.types.VIEW3D_MT_uv_map.append(menu_func)

Commentary

Submenu class

The submenu class is basically the same as the class used to create a normal menu, and inherits the bpy.types.Operator class. As a confirmation, let's add a variable called out_text to the submenu so that out_text will be output when the menu is executed.

submenu_2.py


#Submenu
class SubMenu(bpy.types.Operator):
    bl_idname = "uv.hoge_sub"
    bl_label = "Sub Hoge Menu"
    out_text = bpy.props.StringProperty()

    def execute(self, context):
        self.report({'INFO'}, self.out_text)
        return {'FINISHED'}

Main menu class

Since the main menu needs to create a menu on the tree, it inherits from the bpy.types.Menu class. Furthermore, the main menu does not need to think about what happens when it is selected, and the execute method is unnecessary. Instead, you need to add a draw method to display the menu. Inside the draw method, the submenu is registered by assigning the bl_idname of the subclass of bpy.types.Operator to the argument of layout.operator, and the character string is assigned to the member variable out_text of the registered submenu. I am.

submenu_3.py


#Main menu
class Menu(bpy.types.Menu):
    bl_idname = "uv.hoge"
    bl_label = "Hoge Menu"
    bl_description = "Hoge Piyo"

    def draw(self, context):
        layout = self.layout
        #Submenu registration + output character string registration
        layout.operator(SubMenu.bl_idname).out_text = "Sub Hoge Menu"

Registration

The registration part is almost the same as the normal part, but the menu_func called from the function specified in the argument of bpy.types.VIEW3D_MT_uv_map.append has been modified. It has nothing to do with creating a submenu, but you can add a separate to the menu by executing the self.layout.separator function. This makes it clearly distinguishable from other menus and makes the menus added by installing the plugin easier to understand. You can register the menu on the tree by passing the bl_idname of the derived class of bpy.types.Menu as the argument of the self.layout.menu function.

submenu_4.py


#Register in the menu displayed when you press "U" in Edit mode (bpy).types.VIEW3D_MT_uv_map.append(menu_func)Called from)
def menu_func(self, context):
    self.layout.separator()            #Register separator in menu
    self.layout.menu(Menu.bl_idname)

#Registration
def register():
    bpy.utils.register_module(__name__)
    bpy.types.VIEW3D_MT_uv_map.append(menu_func)

Sample plugin

Here is the code of the sample plug-in that actually works, summarizing the above contents.

submenu.py


#Required to access data structures inside Blender
import bpy

#Information about plugins
bl_info = {
    "name" : "Hoge Plugin",             #Plugin name
    "author" : "Piyo",                  #author
    "version" : (0,1),                  #Plugin version
    "blender" : (2, 6, 5),              #The version of Blender where the plugin works
    "location" : "UV Mapping > Hoge",   #Positioning of plugins inside Blender
    "description" : "Hoge Fuga Piyo",   #Plugin description
    "warning" : "",
    "wiki_url" : "",                    #URL of the wiki page where the plugin description is located
    "tracker_url" : "",                 #Blender Developer Org thread URL
    "category" : "UV"                   #Plugin category name
}

#Submenu
class SubMenu(bpy.types.Operator):
    bl_idname = "uv.hoge_sub"
    bl_label = "Sub Hoge Menu"
    out_text = bpy.props.StringProperty()

    def execute(self, context):
        self.report({'INFO'}, self.out_text)
        return {'FINISHED'}

#Main menu
class Menu(bpy.types.Menu):
    bl_idname = "uv.hoge"
    bl_label = "Hoge Menu"
    bl_description = "Hoge Piyo"

    def draw(self, context):
        layout = self.layout
        #Submenu registration + output character string registration
        layout.operator(SubMenu.bl_idname).out_text = "Sub Hoge Menu"

#Register in the menu displayed when you press "U" in Edit mode (bpy).types.VIEW3D_MT_uv_map.append(menu_func)Called from)
def menu_func(self, context):
    self.layout.separator()            #Register separator in menu
    self.layout.menu(Menu.bl_idname)

#Registration
def register():
    bpy.utils.register_module(__name__)
    bpy.types.VIEW3D_MT_uv_map.append(menu_func)

#What happens when you uninstall the plugin
def unregister():
    bpy.utils.unregister_module(__name__)
    bpy.types.VIEW3D_MT_uv_map.remove(menu_func)

#Main function
if __name__ == "__main__":
    register()

How to run the sample plugin

Let's actually operate the above sample plugin. The procedure for installing the plug-in is as follows. The installation procedure is also described on the Blender Wiki page. http://wiki.blender.org/index.php/Doc:JA/2.6/Manual/Extensions/Python/Add-Ons

  1. Select File-User Preferences
  2. Select the Addons tab
  3. Press the "Install from File ..." button
  4. Select the plugin you want to install
  5. Select the check box next to the installed plugin
  6. Press "U" in "Edit Mode"
  7. Confirm that "Hoge Menu" is a tree-like menu.
  8. Click "Hoge Menu"-"Sub Hoge Menu" to execute the process ("Sub Hoge Menu" is displayed in the log).

Execution result

Tree-shaped menu display

20141118230248.jpg

Execution result of "Sub Hoge Menu"

20141118230358.jpg

References

Recommended Posts

How to create a submenu with the [Blender] plugin
[Blender] How to make a Blender plugin
How to create a multi-platform app with kivy
[Python] How to create a 2D histogram with Matplotlib
How to create a Conda package
How to create a virtual bridge
How to create a Dockerfile (basic)
How to create a config file
Probably the easiest way to create a pdf with Python3
How to create a flow mesh around a cylinder with snappyHexMesh
A story about how to deal with the CORS problem
[Blender] How to set shape_key with script
How to create a clone from Github
How to create a git clone folder
How to add a package with PyCharm
[Introduction to Python] How to split a character string with the split function
How to make a command to read the configuration file with pyramid
How to create a heatmap with an arbitrary domain in Python
How to create a label (mask) for segmentation with labelme (semantic segmentation mask)
Create a star system with Blender 2.80 script
How to create a repository from media
How to write a docstring to create a named tuple document with sphinx
Create a devilish picture with Blender scripts
How to send a request to the DMM (FANZA) API with python
Create a REST API to operate dynamodb with the Django REST Framework
How to create a serverless machine learning API with AWS Lambda
Think about how to write a filter with the Shotgun API-Contact Versions
[Python] Explains how to use the range function with a concrete example
I tried to create a plug-in with HULFT IoT Edge Streaming [Development] (2/3)
[Introduction to Python] How to sort the contents of a list efficiently with list sort
I tried to create a plug-in with HULFT IoT Edge Streaming [Execution] (3/3)
How to fix the initial population with a genetic algorithm using DEAP
How to create a wrapper that preserves the signature of the function to wrap
[Introduction to Python] How to write a character string with the format function
[Development environment] How to create a data set close to the production DB
I tried to create a plug-in with HULFT IoT Edge Streaming [Setup] (1/3)
3. Natural language processing with Python 1-2. How to create a corpus: Aozora Bunko
How to create sample CSV data with hypothesis
How to read a CSV file with Python 2/3
How to send a message to LINE with curl
How to create a Python virtual environment (venv)
How to specify the NIC to scan with amazon-dash
How to draw a 2-axis graph with pyplot
How to create a function object from a string
How to develop a cart app with Django
How to create a JSON file in Python
How to make a dictionary with a hierarchical structure.
How to try the friends-of-friends algorithm with pyfof
How to make a QGIS plugin (package generation)
Steps to create a Twitter bot with python
How to create a shortcut command for LINUX
I want to create a plug-in type implementation
Save the object to a file with pickle
[Note] How to create a Ruby development environment
How to create a Kivy 1-line input box
How to create a Rest Api in Django
How to Learn Kaldi with the JUST Corpus
Create a command to get the work log
Create a translation tool with the Translate Toolkit
[Note] How to create a Mac development environment
How to create random numbers with NumPy's random module