3
$\begingroup$

How do I detect a modifier specific modifier name and type and use this to create and if/else statement to disable a row.operator(Button) in my custom panel ?

$\endgroup$
5
$\begingroup$

It is not the panel's job to decide if a button is enabled/disabled, the operator is responsible for deciding if it is able to be run with the current selection. The poll method of the operator class is used to determine if the operator can be run, if the poll method returns False then it's button will be disabled in your panel.

class myOperator(bpy.types.Operator):
    bl_idname = 'object.testing'
    bl_label = 'Simple test setup'

    @classmethod
    def poll(cls, context):
        mod_types = set()
        for o in context.selected_objects:
            for m in o.modifiers:
                mod_types.add(m.type)
        return 'ARRAY' in mod_types

    def execute(self, context):
        # do stuff
        return {'FINISHED'}

A panel can look through the context and adjust it's content based on the current selection, note that it is altering it's content and not disabling an item.

class samplePanel(bpy.types.Panel):
    bl_idname = "OBJECT_PT_example"
    bl_label = "Dynamic content"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'

    def draw(self, context):
        mod_types = set()
        for o in context.selected_objects:
            for m in o.modifiers:
                mod_types.add(m.type)
        row = self.layout.row()
        if 'ARRAY' in mod_types:
            row.label(text='there is an array modifier')
        else:
            row.label(text='No object using an array')
$\endgroup$
2
  • $\begingroup$ Thank you but how do I detect the modifier based on the name and type ? $\endgroup$
    – Retrax
    Jun 15 '17 at 13:48
  • $\begingroup$ The example uses m.type you can add m.name to consider both. Note that the name is editable and can get a numeric extension like .001 added to it so may not be a simple match. $\endgroup$
    – sambler
    Jun 16 '17 at 1:09
4
$\begingroup$

If you are used to other UIs, each "control" can be enabled or disabled - without the need to poll.

As operators don't have an enabled property and rely on the poll() function, the alternative I discovered is to place the operator inside a container, and use the container's enabled property instead to manage the state of the operator (grayed out).

This is what you usually find in UIs such as .NET, QT or others.

The poll function works well in most cases, but there are edge cases.

def draw(layout, context):
    row = layout.row()
    c1 = row.column()
    c2 = row.column()
    c1.operator(MY_OT_Operator.bl_idname,text='This operator is disabled by its container')
    c1.enabled = False
    c2.operator(MY_OT_Operator.bl_idname,text='This operator is enabled by its container')
$\endgroup$
1
  • $\begingroup$ Suggest a clarification. The edge case would be re disabling an operator that does poll, not vice versa, ie enabling an op that doesn't poll. $\endgroup$
    – batFINGER
    Apr 24 '20 at 10:16

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.