You need to be aware that Blender, when changing such custom properties, internally runs an undo step, and then re-executes the script. The trouble with your script is that you define the content of the variable
cube right in the
__main__ area of your script. This means it is only run once when the script registers. When the undo->redo happens, this can get lost. In fact, when I just copy-paste your code into a new file, run the script, run the operator and toggle the property, the pasted script disappears (pasting it is also undone in the undo step).
To fix it, get the cube while executing. It could also make sense to get it in the invoke() function, but let's keep it simple for now. So try this modified script instead:
from bpy.props import BoolProperty
bl_idname = "object.hello_error"
bl_label = "HelloError"
my_property= BoolProperty(name="my_property", default=True)
def execute(self, context):
# get desired object within execute() function instead!!
# also, retrieve it from the current scene objects,
# this ensures it exists within the scene and can be set active
cube = context.scene.objects.get("Cube")
#set the active object as a existed cube
if __name__ == "__main__":
I've done a few other style modifications to it, namely using the
context variable that is passed into the
execute() method instead of constantly grabbing it from
bpy.context, and using
context.blend_data instead of bpy.data (a call which I removed later on, see next paragraph).
Finally, batFINGER pointed out in a comment that it is recommended to pull the cube object from
context.scene.objects instead of context.blend_data.objects, as this will make sure the cube is already linked to the scene, and later on can be set as active object. Using the get() method, the variable will be set to None if there is no object named
Cube, instead of throwing an error immediately. You could later on use a sanity check like:
if not cube: