2
$\begingroup$

I have two scripts I've been making pie menus in the last few weeks and I came across a seeming inconsistency in how blender handles classes and their labeling. I have two examples. One is the Viewport_Pie_Menu.py script by Wazou, modified for my own uses (single file); the other is a mesh multiselect script (part of a package and imported with __init__.py as a module). I've cut down the code snippets to illustrate my point.

Viewport Pies

This is the first class, the called menu that pops up when you press Shift+Space:

class PieAreaViews(Menu):
bl_label = "Pie Views"

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

    pie.operator("wm.call_menu_pie", text="Images", icon='IMAGE_COL').name = "PieAreaViewsImage"
    pie.operator("wm.call_menu_pie", text="Split", icon='SPLITSCREEN').name = "pie.split_viewport"
    ...

This calls a number of subpies, the first of which changes editors:

class PieAreaViewsImage(Menu):
bl_label = "Image"

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

    pie = layout.menu_pie()
    pie.operator("object.view_menu", text="Node Editor", icon='NODETREE').variable = "NODE_EDITOR"
    ...

Another is a subpie with some operators in it:

class PieSplitViewport(Menu):
bl_idname = "pie.split_viewport"
bl_label = "Split Viewport"

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

    pie.operator("split.vertical", text="Vertical", icon='DOWNARROW_HLT')
    pie.operator("split.horizontal", text="Horizontal", icon='RIGHTARROW')

Multiselect

The main pie class:

class VIEW3D_MT_Multiselect_Menu_Pie(Menu):
bl_label = "Multiselect Pie"

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

    pie.operator("multi.vert", text="Vertex Select", icon='VERTEXSEL')
    ...
    pie.operator("wm.call_menu_pie", text="Multiselect", icon='FACESEL').name = "MultiPie"

Subpie:

class MultiPie(Menu):
bl_label = "Multiselect Options"

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

    pie.operator("multi.vertedge", text="Vertex/Edge", icon='EDITMODE_HLT')
    ...

The final operation:

class SelModeVert(bpy.types.Operator):
bl_idname = "multi.vert"
bl_label = "Vertex Select Mode"

def execute(self, context):
    bpy.ops.wm.context_set_value(data_path="tool_settings.mesh_select_mode", value="(True, False, False)")
    return {'FINISHED'}

Observations

Some classes include bl_idname while others do not. Operators have them, but Menus do not. If the class does not have bl_idname, I can call it with the class name, but if it does have bl_idname, it can only sometimes be called with its class and sometimes by its bl_idname string. If a Menu type includes bl_idname, you can't call it with either bl_idname string or class name.

It took me a long time to figure out I couldn't spawn my subpie simply because it contained bl_idname, which I was then calling (I couldn't call it with either bl_idname or class name), nor could I assign a hotkey through init.

Questions

Why do some types need bl_idname and others do not? Wouldn't it be better to be consistent? If I understand right, bl_idname is required if you want to search from the spacebar search menu, but you can give bl_options = {'INTERNAL', ...} to disallow searching.

Is this how blender really treats these class types or am I just being inconsistent myself? Is there a better way to handle this? What are some conventions you have found?

I will follow this convention for now, but I'm not entirely familiar with how blender handles classes and context and whatnot. I would still consider myself relatively fresh with Python, especially within blender, so any help would be appreciated.

$\endgroup$

Your Answer

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

Browse other questions tagged or ask your own question.