UILayout.visible?

Hi,

is it possible to hide/collapse a portion of the GUI dynamically, eg, based on the value of an EnumProperty? I know how to set UILayout.active and ~.enabled, but that only deactivates the layout; it’s still visible on the panel/screen. Is there any way to completely remove/hide a component of a UILayout?

Thanks,
g

Hi guy,

AFAIK

It’s either use the poll method to completely hide a panel,

otherwise logic


if obj.enum_prop == 'BLAH':
    row = layout.row()
    row.prop(...

Alright, thanks, batFINGER. I’ll go for the second option, I guess.

Unless… Can you put a panel inside a panel?

A panel in a panel would be great. Suggested it on IRC to deaf ears. SubPanels that can be coded to open shut sort etc would be very handy as another way to display an expandable list using the draw_header. The drag drop behaviour would be restricted to inside the parent Panel. I understand the reasoning behind not being able to move close panels… it would lead to a race from addon designers to close all the rest and live on the top… lol.

Ok, so a panel inside a panel is out; thanks for clearing that up.

I’m not sure I understand what you’re saying about draw_header, though. How does me putting a subpanel inside my main panel relate to me being able to move/close your panel? Can I even see your panel from within my code? And even if I could, I wouldn’t even dream of closing it, as that would be very rude, indeed…

Which panels are you trying to hide? Your own or blender’s?

If you are trying to hide blender’s stuff you need to get a reference to the class in bpy.types, hang on to that reference while you unregister the class, override the poll or draw method, then re-register. From that point on what you have is utterly hackish but it works.

I figured out how to wipe out all of blender’s panels because I thought I would be nice for an addon to have more “room for activities”.

It can be done but in the end I decided it is more of a novelty than a good feature.

not sure what the problem is?

if self.vertices_type == 'VORONOI':
    box = layout.box()
    box.prop(self, "voronoi_offset")
    # ...

No problem; we just got a little side-tracked with the panel inside a panel thing… :slight_smile:

My original question has been solved the way you and batFINGER have suggested. I’ll mark the thread as solved.

You can’t have a panel inside a panel, you can embed a panel’s draw function in another panel however

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_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "object"

    @classmethod
    def poll(cls, context):
        # e.g. always hide
        return False
    
    @classmethod
    def poll_embedded(cls, context):
        return context.object.type == 'MESH'

    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")
        
        
class HelloWorldPanel2(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "Hello World Panel 2"
    bl_idname = "OBJECT_PT_hello2"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "object"

    def draw(self, context):
        layout = self.layout
        
        layout.label("Embed another panel:")
        
        context.window_manager.hello_world_embedded = True
        if HelloWorldPanel.poll_embedded(context):
            HelloWorldPanel.draw(self, context)



def register():
    bpy.utils.register_class(HelloWorldPanel)
    bpy.utils.register_class(HelloWorldPanel2)


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


if __name__ == "__main__":
    register()


Alright, that sure is good to know! It’s not quite the ‘visible’ property yet, but it definitely comes very close. At least, it allows me to achieve what I’m looking for, ie, to put different chuncks of the interface in separate classes/files, and show/hide them dynamically.

Thanks, CoDEmanX!