0
$\begingroup$

NOTE : There are already two posts concerning this problem but I can't find an answer in them. I enclose the link that leads to it: Answers

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()
$\endgroup$
  • 2
    $\begingroup$ 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. $\endgroup$ – brockmann Mar 9 at 15:37
1
$\begingroup$

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.

UI panel

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()
| improve this answer | |
$\endgroup$
  • $\begingroup$ @brockmann I guess that's a matter of personal preferences. The label is only created once per draw call in both cases. $\endgroup$ – Robert Gützkow Mar 9 at 18:10
  • $\begingroup$ Thanks, I never would've figured it out on my own. $\endgroup$ – pierre950 Mar 9 at 21:02
  • $\begingroup$ 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, $\endgroup$ – pierre950 Mar 10 at 20:24
  • $\begingroup$ @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. $\endgroup$ – Robert Gützkow Mar 10 at 20:29
  • $\begingroup$ 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? $\endgroup$ – pierre950 Mar 12 at 19:45

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.