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$
2
  • $\begingroup$ I think you mean the Shift + A menu, CTRL + A is Apply not Add. $\endgroup$
    – Robert Gützkow
    Oct 22, 2019 at 13:25
  • $\begingroup$ Yes, sorry, I'll edit the question right away, thanks $\endgroup$
    – Tareyes
    Oct 22, 2019 at 13:27

1 Answer 1

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$
3
  • $\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, 2019 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, 2019 at 15:26
  • $\begingroup$ Thanks for the clarification! $\endgroup$
    – Tareyes
    Oct 22, 2019 at 15:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .