Dynamic Menu

Hi,

I can pass a variable to an operator class but I don’t seem to be able to do it with a menu class.


bl_info = {
    "name": "Menu Dynamic",
    "description": "Dynamic menu test.",
    "author": "rarebit",
    "version": (0, 0, 1),
    "blender": (2, 5, 7),
    "api": 35968,
    "location": "View3D > Add > Mesh",
    "warning": "Currently under development.", 
    "wiki_url": "",
    "tracker_url": "",
    "category": "Add Mesh"}

import bpy

class MyMesh_Add(bpy.types.Operator):
    bl_idname = "mesh.primitive_dmd_add"
    bl_label = "DM Add"
    bl_options = {'REGISTER', 'UNDO'}
    
    def execute(self, context):
        print("Menu execution: Insert")
        return {'FINISHED'}
    
class MyMesh_new(bpy.types.Operator):
    bl_idname = "mesh.primitive_dm_add"
    bl_label = "DM New Caller"
    bl_options = {'REGISTER', 'UNDO'}
    name = bpy.props.StringProperty()
    
    def execute(self, context):
        print("Menu execution: New")
        return{'FINISHED'}

class INFO_MT_mesh_mymesh_menussub_add(bpy.types.Menu):
    bl_idname = "INFO_MT_mesh_dm_msub_add"
    bl_label = "DM Add"
    namex = bpy.props.StringProperty()
    
    def draw(self, context):
        layout = self.layout  
        layout.operator_context = 'INVOKE_REGION_WIN'
        
        #    MAIN MENU ENTRY
        if self.namex == "One":
            layout.operator("mesh.primitive_dmd_add", text='One', icon='LAMP_POINT')
        else:
            layout.operator("mesh.primitive_dmd_add", text='Two', icon='LAMP_POINT')
        
class INFO_MT_mesh_dm_menus_add(bpy.types.Menu):
    bl_idname = "INFO_MT_mesh_dm_menus_add"
    bl_label = "DM"
    
    def draw(self, context):
        layout = self.layout  
        layout.operator_context = 'INVOKE_REGION_WIN'
        
        #    MAIN MENU ENTRY
        layout.operator("mesh.primitive_dmd_add", text='Add new', icon='LAMP_POINT')
        
        self.layout.menu("INFO_MT_mesh_dm_msub_add", text='Menu One', icon='LIBRARY_DATA_DIRECT').namex="One"
        self.layout.menu("INFO_MT_mesh_dm_msub_add", text='Menu Two', icon='LIBRARY_DATA_DIRECT').namex="Two"

#    Registration
#    ==========================================================================
def menu_func(self, context):
    self.layout.menu("INFO_MT_mesh_dm_menus_add", icon='LIBRARY_DATA_DIRECT')

def register():
    bpy.utils.register_module(__name__)
    bpy.types.INFO_MT_mesh_add.append(menu_func)
    
def unregister():
    bpy.utils.unregister_module(__name__)
    bpy.types.INFO_MT_mesh_add.remove(menu_func)

if __name__ == "__main__":
    register() 

Written as an Add-on using Blender 2.57 (Python 3.2), an entry to the “Shift + A” menu, under “Mesh”, named “DM”.

It’ll basically work but throw an “AttributeError” concerning “namex”. (Comment out .namex="*" to see a basic error-less version)

Basically i’m after doing some sub menus, but won’t know the contents until it gets there, and would like to do it in the same manner as if it was the operator class.

Cheers!

I see what your saying and it will be useful for another part of this same project.

This code already does something similar, however I’m after having menus stemming from menus, but desiring to use the same class for all sub menus, hence why I want to pass variables.

Why can I not pass / access ‘namex’?

namex = bpy.props.StringProperty()

self.layout.menu("INFO_MT_mesh_dm_msub_add", text='Menu Two', icon='LIBRARY_DATA_DIRECT').namex="Two"

The second menu doesn’t even get made… If the property ‘namex’ isn’t passed both menus get made, but both sub menus are the same because no identifier is being passed!

I’m also interested … have you solved this problem?

I tried to make an operator with some enum properties load dynamically and the use this method

operator_menu_enum()

but i don’t know the sintax and how to use it well and so doesn’t work now to me…