Adding an Operator to the Context Menu of a UIList

How may I add an operator to the Context Menu of a UI List?

Context menus seem to be defined per Spaces (e.g. NODE_MT_context_menu in the below code). Could this be set for the menu of a region? Thank you!

def draw_menu(self, context):
    layout = self.layout
    layout.operator("node.duplicate_move", text="My new context menu item")

def register():

def unregister():

I’m not aware of a way to do this, typically uilist context menus are shown via a button to the right of the list (including all of the uilists native to Blender)


Thank you for the reply!

You can override the context menus for buttons and ui list items.
See Add Operator to Right Click Menu for Operators - #2 by iceythe

Here’s an example that adds a label to the context menu when a vertex group is right clicked.

import bpy

class WM_MT_button_context(bpy.types.Menu):
    bl_label = ""
    # Leave empty for compatibility.
    def draw(self, context): pass

# Your draw function.
def draw(self, context):
    if hasattr(context, "button_pointer"):
        print("Clicked: ", context.button_pointer)

        if isinstance(context.button_pointer, bpy.types.VertexGroups):
            layout = self.layout
            layout.label(text="I'm in vertex groups context menu!")

    if hasattr(context, "button_prop"):
        print("Property:", context.button_prop.identifier)

    if hasattr(context, "ui_list") and context.ui_list is not None:
        print("UI List: ", context.ui_list.bl_idname)

if __name__ == "__main__":
    # Register menu only if it doesn't already exist.
    rcmenu = getattr(bpy.types, "WM_MT_button_context", None)
    if rcmenu is None:
        rcmenu = WM_MT_button_context

    # Retrieve a python list for inserting draw functions.
    draw_funcs = rcmenu._dyn_ui_initialize()


@iceythe Thank you for this! It works with Vertex Groups as “Clicked” prints <bpy_struct, VertexGroups at 0x000001AC0DAF3908>

However, when I right click in my UIList, it prints <bpy_struct, Scene("Scene") at 0x000001AC0DBC2048>

Have I set something up incorrectly, context-wise, in my UIList/Panel?

Thank you

If your ui list is at context.scene.mylist, then context.button_pointer points to context.scene, so that seems correct.

The draw function prints a few things from context, if they exist:

context.button_pointer: The object you registered your ui list on. The scene in this case.
context.button_prop: The name of your ui list e.g mylist in context.scene.mylist.
context.ui_list: The ui list object itself, if Blender finds it. Otherwise None.

Using these values, and assuming the context holds any of these, you should be able to build a predicate in the draw function, so that your custom entry only is drawn when the right click menu is invoked on your ui list specifically.


def draw(self, context):
    ui_list = getattr(context, "ui_list", None)
    if ui_list is not None and ui_list == context.scene.mylist:
        # Draw operator here
def draw(self, context):
    if hasattr(context, "button_pointer"):
        if getattr(context.button_pointer, "mylist"):
            # Draw operator here
1 Like

You have been a wonderful help as always, @iceythe . Thank you so much!

1 Like