2
$\begingroup$

I'm using layout.popover(my_panel) to draw a panel in a box when it is clicked on, but I don't want that panel to be visible anywhere else in the UI. Just removing the bl_category setting from the panel class simply puts it in a category named "misc".

I realise that one solution could be to change the bl_region_type to something different, but if I change it to something like "TEMPORARY" it just gives me an error.

Is there a correct way to do this, or would it be better to do it from say the invoke method of an operator?

$\endgroup$
4
$\begingroup$

Add 'INSTANCED' to panel options

Edit Credit to @Nilson (finally twigged)

How to hide a panel that appears twice?

I found the solution .. and it was very simple. Just use: bl_options = {"INSTANCED"}. The popover menu is just an instance of the panel

enter image description here

If the 'INSTANCED' option is added to the panels bl_options the panel is not drawn directly in the UI, it is rather instanced via the popup call.

PLEASE Note. If the region is set to 'UI' a "Misc" category tab is added, which when selected shows no panels (No others in region and uncategorized) and (for me) segfaults blender when selected. The 'WINDOW' region appears a safe bet.

Test script using the Text Editor > Templates > Pythone > UI Panel Simple script modified to add to view3d UI (N) region. Making only the options edit confirms the panel no longer renders in the properties region.

import bpy


class HelloWorldPanel(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "Hello World Panel"
    bl_idname = "OBJECT_PT_hello"
    bl_options = {'INSTANCED'}
    #bl_options = {'INSTANCED', 'DRAW_BOX'}
    bl_space_type = 'VIEW_3D' # 'PROPERTIES'
    bl_region_type = 'WINDOW'
    #bl_context = "object"

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

        obj = context.object

        row = layout.row()
        row.label(text="Hello world!", icon='WORLD_DATA')

        row = layout.row()
        row.label(text="Active object is: " + obj.name)
        row = layout.row()
        row.prop(obj, "name")

        row = layout.row()
        row.operator("mesh.primitive_cube_add")

def draw(self, context):
    self.layout.popover("OBJECT_PT_hello")
def register():
    bpy.utils.register_class(HelloWorldPanel)
    bpy.types.VIEW3D_PT_view3d_cursor.prepend(draw)


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


if __name__ == "__main__":
    register()

Tip. If set an enum to a garbage value can look at the error message to get allowable values

TypeError: validating class: enum "FOO" not found in 
('WINDOW', 'HEADER', 'CHANNELS', 
'TEMPORARY', 'UI', 'TOOLS', 'TOOL_PROPS',
 'PREVIEW', 'HUD', 'NAVIGATION_BAR',
 'EXECUTE', 'FOOTER', 'TOOL_HEADER')

Fwiw 'HUD' adds panel to operator redo panel.

$\endgroup$

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.