# How to make the panel detect that the operator has been executed correctly?

Hy everyone,

I have in my script, a panel and an operator. I try to make sure that when the operator executes it puts a interne boolean variable to "True" and then make some elements of the panel display. I manage to access the operator's variable from the panel but I can't set this variable to "True" in the operator's execute. test_bool stays at "false".

Have a nice day.

The code looks like this :

def _build_bones_list():

#code...

class OP_ListBones(bpy.types.Operator) :

bl_idname = "object.oper_list_bones"
bl_label = "list bones!"
bl_description = "enregistre la liste des bones d'une armature"

test_bool=False

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

def execute(self, context) :

_build_bones_list()
self.test_bool= True #don't work
return {'FINISHED'}

class InterfacePanel (bpy.types.Panel) :

bl_label = "Parent Bones..."
bl_idname = "VIEW_3D_PT_PARENT_BONES"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = "Parent bones"
bl_description = "parentage robot mesh/bones"

_bool_=False

# --- interface_listener ---

def interface_listener(self) :

obj_select = bpy.context.selected_objects #list
obj_ = bpy.context.object #obj selected

l = self.layout
c=l.column(align = False)

if not obj_select or not obj_.type == "ARMATURE" :

l.label(text ="select an armature!!")
return

elif obj_.type == "ARMATURE":

#code...

c.operator(OP_ListBones.bl_idname)

#I'm trying to retrieve the boolean from the operator...
self._bool_ = OP_ListBones.test_bool

#code...

# --- interface_parent ---

def interface_parent(self) :

#code...

def draw(self, context) :

if not self._bool_ :

self.interface_listener()

elif self._bool_ :

self.interface_parent()

• Add a settings class (PropertyGroup) for a global property and set it to the value when the operator is executed properly: blender.stackexchange.com/a/57332/31447 Operator property is not helpful in this case. – brockmann Mar 9 '20 at 15:37

The add-on below demonstrates how to solves this by using a PropertyGroup that stores the state of the execution. The operator SCENE_OT_example toggles the value stored in bpy.context.scene.example_settings.success. In EXAMPLE_PT_panel the draw() method is used to display a label depending on the value of bpy.context.scene.example_settings.success.

bl_info = {
"name": "Example Report Operator Success",
"author": "Robert Guetzkow",
"version": (1, 0),
"blender": (2, 80, 0),
"location": "View3D > Sidebar > Example tab",
"description": "Example Report Operator Success",
"warning": "",
"wiki_url": "",
"category": "3D View"}

import bpy

class ExampleSettings(bpy.types.PropertyGroup):
success: bpy.props.BoolProperty(description='Operator executed successfully.', default=False)
executed: bpy.props.BoolProperty(description='Operator has been executed.', default=False)

class SCENE_OT_example(bpy.types.Operator):
bl_idname = "scene.example"
bl_label = "Example Operator"
bl_description = "Sets the success variable."
bl_options = {"REGISTER", "UNDO"}

def execute(self, context):
context.scene.example_settings.executed = True

# Dummy function that toggles the value (True => False, False => True)
context.scene.example_settings.success = not context.scene.example_settings.success
return {"FINISHED"}

class EXAMPLE_PT_panel(bpy.types.Panel):
bl_label = "Panel 1"
bl_category = "Example tab"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_options = {"DEFAULT_CLOSED"}

def draw(self, context):
layout = self.layout
layout.operator(SCENE_OT_example.bl_idname)

if context.scene.example_settings.executed:
if context.scene.example_settings.success:
layout.label(text="Operator execution successful.")
else:
layout.label(text="Operator execution failed.")

classes = (ExampleSettings, SCENE_OT_example, EXAMPLE_PT_panel)

def register():
for cls in classes:
bpy.utils.register_class(cls)
bpy.types.Scene.example_settings = bpy.props.PointerProperty(type=ExampleSettings)

def unregister():
for cls in classes:
bpy.utils.unregister_class(cls)
del bpy.types.Scene.example_settings

if __name__ == "__main__":
register()

• @brockmann I guess that's a matter of personal preferences. The label is only created once per draw call in both cases. – Robert Gützkow Mar 9 '20 at 18:10
• Thanks, I never would've figured it out on my own. – pierre950 Mar 9 '20 at 21:02
• Hy @Robert Gützkow I have integrated this solution into my code, but something strange is going on. Although at the beginning the boolean property is by default at "False" this one is at "True" When I read them. And it happens even if in my code I just read them in the console without modifying them in the code from the draw function of the InterfacePanel class. The weirdest thing is that I manage to reset them to "false" from time to time by changing the variable names but when I restart it goes back to True. Have you ever had this kind of problem before? Have a good night, – pierre950 Mar 10 '20 at 20:24
• @pierre950 Check all parts of your code that assign a value to the BoolProperty. There's likely something executed at a time you're not expecting it. Also check for common mistakes such as doing an assignment instead of a comparison. – Robert Gützkow Mar 10 '20 at 20:29
• Sorry to bother you, I searched a lot and I ended up implementing the boolean property in window manager instead of scene after reading that window manager doesn't keep data in memory unlike scene. Since then, everything works fine. Do you think it makes sense? – pierre950 Mar 12 '20 at 19:45