0
$\begingroup$

Display Mode of Object

I wanted to switch between Display modes with hot keys.

And I decided to write my own operator for this and create a small add-on to be able to start using hot keys and switch between these modes. The operator itself works.

import bpy

def main(context):
    bpy.context.object.display_type = 'TEXTURED'
    #bpy.ops.mesh.primitive_plane_add(enter_editmode=False, location=(0, 0, 0))

class SimpleOperator(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "object.simple_operator"
    bl_label = "Simple Object Operator"

    @classmethod
    def poll(cls, context):
        return True

    def execute(self, context):
        main(context)
        return {'FINISHED'}

But when I started working with creating a button for my operator, there were problems.

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

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


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


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


if __name__ == "__main__":
    register()

When I click on the button to apply my operator, an error appears:

    Error: Traceback (most recent call last):
  File "\ui_panel.py", line 31, in execute

  File "\ui_panel.py", line 16, in main
    bpy.context.object.display_type = 'TEXTURED'

AttributeError: 'NoneType' object has no attribute 'display_type'

location: <unknown location>:-1

What is the problem? Why, if you call the operator directly, then it works, and if through the button it throws an error? Why is this happening and how to fix it?

$\endgroup$
5
  • $\begingroup$ For some reason bpy.context.object return None in script with button what call operator while if execute operator itself with debugging bpy.context.object it return selected object $\endgroup$ Commented Jul 9, 2020 at 23:48
  • $\begingroup$ I solve the problem, start from beginng creating the same script and it works, I did not fully understand what was the problem, but now it works $\endgroup$ Commented Jul 10, 2020 at 3:43
  • 1
    $\begingroup$ I start new try with templates, there are differences in poll function @classmethod def poll(cls, context): return context.active_object is not None $\endgroup$ Commented Jul 10, 2020 at 3:52
  • 1
    $\begingroup$ Maybe the problem was this $\endgroup$ Commented Jul 10, 2020 at 3:53
  • $\begingroup$ When accessing the context from the operator, you should use the context passed as a parameter of your method, not bpy.context since those can be different $\endgroup$
    – Gorgious
    Commented Jul 10, 2020 at 6:29

1 Answer 1

2
$\begingroup$

change following line in Panel

bl_context = "scene"

to

bl_context = "object"

context passed to draw function in Panels contains current active object only in object specific sections like 'object','data','physics','constraints' etc.

$\endgroup$
2
  • $\begingroup$ Would say this is also specific to buttons context or the PROPERTIES area. Other workarounds would be i) if the panel is for scene context then consider using context.active_object ii) set the context pointer UILayout.context_pointer_set("object", context.active_object) to have context.object visible to operators. $\endgroup$
    – batFINGER
    Commented Sep 18, 2021 at 19:56
  • $\begingroup$ IIRC it also has something to do with area.pin_id $\endgroup$
    – batFINGER
    Commented Sep 18, 2021 at 20:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .