How to enable/disable items in panel

I have a simple panel example:

using the following script:


import bpy


class SimpleOperator(bpy.types.Operator):
    bl_label = "Simple Operator"
    bl_idname = "wm.simple_operator"


    @classmethod
    def poll(cls, context):
        print("Poll called")
        return True


    def execute(self, context):
        self.report({'INFO'}, "Simple Operator executed.")
        return {'FINISHED'}
    
class LayoutDemoPanel(bpy.types.Panel):
    """Creates a Panel in the scene context of the properties editor"""
    bl_label = "Layout Demo"
    bl_idname = "SCENE_PT_layout"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "scene"


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


        scene = context.scene


        # Create a simple row.
        layout.label(text=" Simple Row:")


        row = layout.row()
        row.prop(scene, "frame_start")
        row.prop(scene, "frame_end")


        # Create an row where the buttons are aligned to each other.
        layout.label(text=" Aligned Row:")


        row = layout.row(align=True)
        row.prop(scene, "frame_start")
        row.prop(scene, "frame_end")




        # Big render button
        layout.label(text="Big Button:")
        row = layout.row()
        row.scale_y = 3.0
        layout.operator("wm.simple_operator")






def register():
    bpy.utils.register_class(LayoutDemoPanel)
    bpy.utils.register_class(SimpleOperator)




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




if __name__ == "__main__":
    register()



The question i have is how do i disable the ā€œStart Frameā€ and ā€œEnd Frameā€ controls when the user clicks the ā€œSimple Operatorā€ button?

Do you want it to toggle or is it just a one shot switch?

I want to know how to disable a row in the layout. For example, the row "row.prop(scene.ā€œframe_startā€) , how do i enable or disable it once some event has occurred (like the button being pressed).

I was asking if you wanted to turn it of and on with the button, or just off.
Anyway, you could create a bool property and use it as a switch.


import bpy
from bpy.props import BoolProperty# import bool property


class SimpleOperator(bpy.types.Operator):
    bl_label = "Simple Operator"
    bl_idname = "wm.simple_operator"


    @classmethod
    def poll(cls, context):
        print("Poll called")
        return True


    def execute(self, context):
       #switch bool property to opposite. if you don't toggle just set to False
        context.scene.my_bool_property = not context.scene.my_bool_property
        self.report({'INFO'}, "Simple Operator executed.")
        return {'FINISHED'}
    
class LayoutDemoPanel(bpy.types.Panel):
    """Creates a Panel in the scene context of the properties editor"""
    bl_label = "Layout Demo"
    bl_idname = "SCENE_PT_layout"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "scene"


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


        scene = context.scene


        # Create a simple row.
        layout.label(text=" Simple Row:")


        row = layout.row()
        row.prop(scene, "frame_start")
        row.prop(scene, "frame_end")


        # Create an row where the buttons are aligned to each other.
        if scene.my_bool_property:#if bool property is true, show rows, else don't
            layout.label(text=" Aligned Row:")


            row = layout.row(align=True)
            row.prop(scene, "frame_start")
            row.prop(scene, "frame_end")


        # Big render button
        layout.label(text="Big Button:")
        row = layout.row()
        row.scale_y = 3.0
        layout.operator("wm.simple_operator")


def register():
    bpy.utils.register_class(LayoutDemoPanel)
    bpy.utils.register_class(SimpleOperator)
    bpy.types.Scene.my_bool_property = BoolProperty(name='My Bool Property', default = True)# create bool property for switching


def unregister():
    bpy.utils.unregister_class(LayoutDemoPanel)
    del bpy.types.Scene.my_bool_property#remove property on unregister


if __name__ == "__main__":
    register()


1 Like

Thanks for you help. Is it possible to grey out the label instead of not showing it. I want to use this in a project i am working on and want to show that a input is not longer needed, hence grey out the value and donā€™t allow edit

You do that with layout.enabled bool:


import bpy
from bpy.props import BoolProperty# import bool property




class SimpleOperator(bpy.types.Operator):
    bl_label = "Simple Operator"
    bl_idname = "wm.simple_operator"




    @classmethod
    def poll(cls, context):
        print("Poll called")
        return True




    def execute(self, context):
       #switch bool property to opposite. if you don't toggle just set to False
        context.scene.my_bool_property = not context.scene.my_bool_property
        self.report({'INFO'}, "Simple Operator executed.")
        return {'FINISHED'}
    
class LayoutDemoPanel(bpy.types.Panel):
    """Creates a Panel in the scene context of the properties editor"""
    bl_label = "Layout Demo"
    bl_idname = "SCENE_PT_layout"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "scene"




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




        scene = context.scene




        # Create a simple row.
        layout.label(text=" Simple Row:")




        row = layout.row()
        row.prop(scene, "frame_start")
        row.prop(scene, "frame_end")




        # Create an row where the buttons are aligned to each other.
        
        layout.label(text=" Aligned Row:")
        row = layout.row(align=True)
<b>        row.enabled = context.scene.my_bool_property #magic happens here</b>
        row.prop(scene, "frame_start")
        row.prop(scene, "frame_end")




        # Big render button
        layout.label(text="Big Button:")
        row = layout.row()
        row.scale_y = 3.0
        layout.operator("wm.simple_operator")




def register():
    bpy.utils.register_class(LayoutDemoPanel)
    bpy.utils.register_class(SimpleOperator)
    bpy.types.Scene.my_bool_property = BoolProperty(name='My Bool Property', default = True)# create bool property for switching




def unregister():
    bpy.utils.unregister_class(LayoutDemoPanel)
    del bpy.types.Scene.my_bool_property#remove property on unregister




if __name__ == "__main__":
    register()

https://www.blender.org/api/blender_python_api_2_78a_release/bpy.types.UILayout.html?highlight=template_list#bpy.types.UILayout.enabled

1 Like

Thanks for your help

Does this same process work for layout.prop as it does for row.label

I defined a variable as you suggested:
bpy.types.Scene.spacingUniform = BoolProperty(name=ā€˜spacingFlagā€™, default = False)

Then used it in the script:
print("context.scene.spacingUniform = ",context.scene.spacingUniform)
row.enabled = context.scene.spacingUniform
layout.prop(myTool,ā€œSpacingā€,text=ā€œSpacing between Objectsā€)

the value of spacingUniform changes but has no effect on the display.

It does, but what youā€™ve done is disabled the row, not the layout, which are two different things. if it were instead:

row.prop(myTool,"Spacing",text="Spacing between Objects")

ā€¦then that row would have been disabled. If it were a box, you would have to disable the box. If it were a column, you would disable the column, etc.

This is an example of the relationships between the layout elements.

Thanks again. But using the line:

    row = layout.row()        row.prop(myTool,"UniformSpacing",text="Spacing between Objects")

just gives me a check box (which does become enabled/disabled). So how do i create a box with the spacing value that can be enabled/disabled? Sorry to sound so stupid, but iā€™m new to this

Iā€™m sorry, Ithink I misunderstood what youā€™re trying to do. So you want a checkbox for your spacingUniform property that enable/disables the row? Then going back to this:

I defined a variable as you suggested:
bpy.types.Scene.spacingUniform = BoolProperty(name=ā€˜spacingFlagā€™, default = False)

Then used it in the script:
print("context.scene.spacingUniform = ",context.scene.spacingUniform)
row.enabled = context.scene.spacingUniform
layout.prop(myTool,ā€œSpacingā€,text=ā€œSpacing between Objectsā€)# is this supposed to be the spacingUniform property?

layout.prop(scene, 'spacingUniform')

ā€¦ would create a checkbox that affect the row.enabled. Is that what youā€™re layout.prop is supposed to be?

Here is a image of the panel

I have attached to script is am using

Attachments

Follow Objects Panel - Test.zip (1.65 KB)

And this is still your property? bpy.types.Scene.spacingUniform = BoolProperty(name=ā€˜spacingFlagā€™, default = False)

Okay, all you have to change is :


row = layout.row()
row.prop(myTool,"Spacing",text="Spacing between Objects")        
row.enabled = myTool.UniformSpacing

Also, line 82 should be:


print("Uniform spacing changed - spacingUniform = ", bpy.context.scene.spacingUniform)

Yes. It is handled in the update routine for the Boolean property ā€œUniform Spacingā€

def uniformSpacingUpdate(self, context):
    context.scene.spacingUniform = not context.scene.spacingUniform
    print("Uniform spacing changed - spacingUniform = ",bpy.types.Scene.spacingUniform)
    
UniformSpacing = BoolProperty(
    name="Uniform Spacing",
    description="Space Evenly",
    update=uniformSpacingUpdate,        
    default = True
    )

Got it. Thanks