9
$\begingroup$

What would be the nicest way to code(in Python) a pie menu in Blender 2.79 or 2.8, that would have another menu as an addition to the standard 8 pie menu choices?

pie menu with an additional traditional menu beneath it


After playing with it for some time I found that this kind of works:

import bpy
from bpy.types import Menu
class VIEW3D_PIE_template(Menu):
    bl_label = "Some Pie Menu"

    def draw(self, context):
        layout = self.layout
        pie = layout.menu_pie()
        pie.operator("mesh.primitive_cube_add")
        pie.operator("mesh.primitive_cube_add")
        pie.operator("mesh.primitive_cube_add")
        pie.operator("mesh.primitive_cube_add")
        pie.operator("mesh.primitive_cube_add")
        pie.operator("mesh.primitive_cube_add")
        pie.operator("mesh.primitive_cube_add")
        pie.operator("mesh.primitive_cube_add")
        pie.separator()
        pie.separator()
        gap = pie.column()
        gap.separator()
        gap.separator()
        gap.separator()
        gap.separator()
        gap.separator()
        gap.separator()
        gap.separator()
        menu = gap.box()
        menu.scale_x = 2.5
        menu.operator("mesh.primitive_monkey_add")
        menu.operator("mesh.primitive_monkey_add")

def register():
    bpy.utils.register_class(VIEW3D_PIE_template)

def unregister():
    bpy.utils.unregister_class(VIEW3D_PIE_template)

if __name__ == "__main__":
    register()

    bpy.ops.wm.call_menu_pie(name="VIEW3D_PIE_template")

enter image description here

I wonder if there is a nicer way. This feels 'hacky' and it would be nice to have a menu that would have expandable sub-menus if that is possible at all. I realize that might be too much to wish for... Any advice?

$\endgroup$
5
  • $\begingroup$ You can just append another menu as a submenu: How to make a sub-menu with Python?, with some formatting it could look like this: pastebin.com/7d8dzpwi. You can also do fully custom stuff with bgl drawing inside modal operator, but you would have to re-implement the pie menu functionality. $\endgroup$ Nov 13, 2018 at 8:02
  • $\begingroup$ Thank you! That really helps. That's all the functionality I wanted. I am still hesitating a bit about the code now - I mean all the separators to go around the pie menu... But it works, so I really appreciate the help. $\endgroup$ Nov 13, 2018 at 8:25
  • $\begingroup$ You can just leave 2 separators there and scale the gap column with gap.scale_y = 5.0 to create the distance, but this could mess with spacing of anything put after the gap.box() item in the column. So multiple separators are imho the best to make the space, I would not worry about it. You can add some comments in the code to make it feel less hacky, like # spacing between pie and column menu followed by the separators. $\endgroup$ Nov 13, 2018 at 9:11
  • $\begingroup$ .... putting the separators in a for loop or a draw_gap(self, layout, count=7): method will "clean" the code up somewhat. $\endgroup$
    – batFINGER
    Nov 13, 2018 at 9:15
  • $\begingroup$ I am just scaling a column with one separator with .scale_y now for the gap. That seems nicer. Other than that I need two separators to start drawing my additional 'menu' at the correct place of the pie menu. I think that will have to be nice enough. $\endgroup$ Nov 13, 2018 at 9:46

2 Answers 2

8
$\begingroup$

The solution I ended up with is the same as discussed in the comments:

import bpy
from bpy.types import Menu
 
class Submenu(Menu):
    bl_label = 'Some Submenu'    
    def draw(self, context):
        layout = self.layout
        layout.label(text="Some Submenu")
        layout.separator()
        layout.operator("mesh.primitive_cube_add", text = "Some Submenu Operator", icon = "BLENDER")
        layout.operator("mesh.primitive_cube_add", text = "Some Submenu Operator", icon = "BLENDER")
        layout.operator("mesh.primitive_cube_add", text = "Some Submenu Operator", icon = "BLENDER")
        layout.operator("mesh.primitive_cube_add", text = "Some Submenu Operator", icon = "BLENDER")
 
class Pie_menu(Menu):
    bl_label = "Some Pie Menu"
    def draw(self, context):
        layout = self.layout
        pie = layout.menu_pie()
        pie.operator("wm.call_menu_pie", text = "Some Other Pie", icon = "RIGHTARROW_THIN").name="Pie_menu"
        pie.operator("mesh.primitive_cube_add", text = "Some Operator", icon = "BLENDER")
        pie.operator("mesh.primitive_cube_add", text = "Some Operator", icon = "BLENDER")
        pie.operator("mesh.primitive_cube_add", text = "Some Operator", icon = "BLENDER")
        pie.operator("mesh.primitive_cube_add", text = "Some Operator", icon = "BLENDER")
        pie.operator("mesh.primitive_cube_add", text = "Some Operator", icon = "BLENDER")
        pie.operator("mesh.primitive_cube_add", text = "Some Operator", icon = "BLENDER")
        pie.operator("mesh.primitive_cube_add", text = "Some Operator", icon = "BLENDER")
        pie.separator()
        pie.separator()
        other = pie.column()
        gap = other.column()
        gap.separator()
        gap.scale_y = 7
        other_menu = other.box().column()
        other_menu.scale_y=1.3
        other_menu.operator("mesh.primitive_cube_add", text = "Some Menu Operator",icon = "BLENDER")
        other_menu.operator("mesh.primitive_cube_add", text = "Some Menu Operator",icon = "BLENDER") 
        other_menu.menu('Submenu', icon='RIGHTARROW_THIN',  text='Some Submenu...')

 
def register():
    bpy.utils.register_class(Submenu)
    bpy.utils.register_class(Pie_menu)
 
def unregister():
    bpy.utils.unregister_class(Submenu)
    bpy.utils.unregister_class(Pie_menu)
 
if __name__ == "__main__":
    register()
 
    bpy.ops.wm.call_menu_pie(name="Pie_menu")

It works exactly as I wanted:

enter image description here

$\endgroup$
2
  • $\begingroup$ hello, is it normal to have Warning: Pie menus with more than 8 items are currently unsupportedthis error message printing every time i call the pie ? $\endgroup$
    – Fox
    Jun 28, 2019 at 19:55
  • $\begingroup$ It is not an error message, it is a warning message - it says so: 'Warning:...' That might be new. I don't think I saw it at the time of writing this. Submenu is not working in 2.80 anymore as well, something must have changed during the development. I'll try to look into it if I have a spare minute. $\endgroup$ Jun 28, 2019 at 20:05
3
$\begingroup$

https://i.imgur.com/vjD6uGU.gif

Warning: Pie menus with more than 8 items are currently unsupported Pies larger than 8 are no longer supported by the blender formula.

Please create a pie with no more than 8 items, including submenu items.

Also, please refer to the submenu specifications in In the case of 2.8

#    layout.label("Some Submenu")
     layout.label(text="Some Submenu")

will work.

import bpy
from bpy.types import Menu


class PIE_MT_Submenu(Menu):
    bl_label = 'Some Submenu'    
    def draw(self, context):
        layout = self.layout
        layout.label(text="Some Submenu")
        layout.operator("mesh.primitive_cube_add", text = "Some Submenu Operator", icon = "BLENDER")
        layout.operator("mesh.primitive_cube_add", text = "Some Submenu Operator", icon = "BLENDER")
        layout.operator("mesh.primitive_cube_add", text = "Some Submenu Operator", icon = "BLENDER")
        layout.operator("mesh.primitive_cube_add", text = "Some Submenu Operator", icon = "BLENDER")

class PIE_MT_Pie_menu(Menu):
    bl_label = "Some Pie Menu"
    def draw(self, context):
        layout = self.layout
        pie = layout.menu_pie()
#        Left
        pie.operator("wm.call_menu_pie", text = "Some Other Pie0", icon = "RIGHTARROW_THIN").name="Pie_menu"
#        Right
        pie.operator("mesh.primitive_cube_add", text = "Some Operator1", icon = "BLENDER")
#        Bottom
        other = pie.column()
        other_menu = other.box().column()
        other_menu.operator("mesh.primitive_cube_add", text = "Some Menu Operator7",icon = "BLENDER")
        other_menu.operator("mesh.primitive_cube_add", text = "Some Menu Operator7",icon = "BLENDER")
        other_menu.operator("mesh.primitive_cube_add", text = "Some Menu Operator7",icon = "BLENDER")
        other_menu.menu('PIE_MT_Submenu', icon='RIGHTARROW_THIN',  text='Some Submenu...')
#        Top   
        pie.operator("mesh.primitive_cube_add", text = "Some Operator2", icon = "BLENDER")
#        Top_left
        pie.operator("mesh.primitive_cube_add", text = "Some Operator3", icon = "BLENDER")
#        Top_right
        pie.operator("mesh.primitive_cube_add", text = "Some Operator4", icon = "BLENDER")
#        Bottom_left
        pie.operator("mesh.primitive_cube_add", text = "Some Operator5", icon = "BLENDER")
#        Bottom_right
        pie.operator("mesh.primitive_cube_add", text = "Some Operator6", icon = "BLENDER")



def register():
    bpy.utils.register_class(PIE_MT_Submenu)
    bpy.utils.register_class(PIE_MT_Pie_menu)

def unregister():
    bpy.utils.unregister_class(PIE_MT_Submenu)
    bpy.utils.unregister_class(PIE_MT_Pie_menu)

if __name__ == "__main__":
    register()

    bpy.ops.wm.call_menu_pie(name="PIE_MT_Pie_menu")
$\endgroup$

You must log in to answer this question.

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