0
$\begingroup$

I have a quick and probably easy question.

I have a working submenu and I want to attach it to the Add Menu (that you get by pressing Shift+A).

import bpy
from bpy.props import (StringProperty, BoolProperty,IntProperty,FloatProperty,FloatVectorProperty,EnumProperty,PointerProperty)
from bpy.types import (Panel,Operator,AddonPreferences,PropertyGroup)

#----------------------------------- FUNCTIONS --------------------------

def menu_func(self, context):
    self.layout.operator_menu_enum(OBJECT_MT_effector_submenu.bl_idname,"type", text="Effector")

#----------------------------------- OPERATORS --------------------------

class EFFECTOR_OT_sphere_effector(bpy.types.Operator):
    bl_idname = "mesh.sphere_effector"
    bl_label = "Add Sphere Effector"
    bl_options = {'REGISTER', 'UNDO'}

    def execute(self,context):
        print("0")
        return {'FINISHED'}

class EFFECTOR_OT_plane_effector(bpy.types.Operator):
    bl_idname = "mesh.plane_effector"
    bl_label = "Add Plane Effector"
    bl_options = {'REGISTER', 'UNDO'}

    def execute(self,context):
        print("1")
        return {'FINISHED'}

#----------------------------------- UI --------------------------

class OBJECT_MT_effector_submenu(bpy.types.Menu):
    bl_idname = "OBJECT_MT_effector_submenu"
    bl_label = "Effector"
    bl_options = {'REGISTER', 'UNDO'}

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

        layout.operator("mesh.sphere_effector")
        layout.operator("mesh.plane_effector")

# ----------------------- REGISTER ---------------------

classes = (
    EFFECTOR_OT_sphere_effector,
    EFFECTOR_OT_plane_effector,
    OBJECT_MT_effector_submenu,
)

def register():
    from bpy.utils import register_class
    for cls in classes:
        register_class(cls)
    bpy.types.VIEW3D_MT_add.append(menu_func)
    bpy.ops.wm.call_menu(name="OBJECT_MT_effector_submenu")

def unregister():
    from bpy.utils import unregister_class
    for cls in reversed(classes):
        unregister_class(cls)
    bpy.types.VIEW3D_MT_add.remove(menu_func)

if __name__ == "__main__":
    register()

(NOTE: the full code is bigger, so there might be some useless code that I didn't delete)

The submenu is working (I have a test call in the code), and I could get a single operator in the menu, but not the whole submenu.

When I call the Add Menu, I get the error rna_uiItemMenuEnumO: operator missing srna 'OBJECT_MT_effector_submenu'

My guess is that there are some problems in the name of the operators/idnames, but I couldn't understand how to do it

$\endgroup$
  • $\begingroup$ I think you mean the Shift + A menu, CTRL + A is Apply not Add. $\endgroup$ – Robert Gützkow Oct 22 at 13:25
  • $\begingroup$ Yes, sorry, I'll edit the question right away, thanks $\endgroup$ – Tareyes Oct 22 at 13:27
1
$\begingroup$

There are two changes necessary to add your custom menu entry.

  1. menu_func has to be modified to add OBJECT_MT_effector_submenu to the menu
  2. Don't call bpy.ops.wm.call_menu in register

The fixed menu_func looks like this:

def menu_func(self, context):
    self.layout.menu("OBJECT_MT_effector_submenu", text="Effector")
$\endgroup$
  • $\begingroup$ Thanks man, it worked! Can I just ask you what the operator_menu_enum() does then? In the templates inside Blender it is used to call submenus... $\endgroup$ – Tareyes Oct 22 at 14:44
  • 1
    $\begingroup$ It can be used to add menu entries based on operators with enum properties. Take a look at the __init__.py in add_curve_extra_objects where it's used in the menu_func. The it uses layout.operator_menu_enum("curve.curveaceous_galore", "ProfileType", icon='CURVE_DATA') which references Curveaceous_galore from add_curve_aceous_galore.py. $\endgroup$ – Robert Gützkow Oct 22 at 15:26
  • $\begingroup$ Thanks for the clarification! $\endgroup$ – Tareyes Oct 22 at 15:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.