# Python : Change cursor icon

in my add on, every execution of my operator, I change my icon cursor. (see code) I have to repeat these two lines of code in all operators or there is a solution to change icon when an operator is running?

def execute(self,context):
bpy.context.window.cursor_set("WAIT")
....
My code
.....

bpy.context.window.cursor_set("DEFAULT")
return {'FINISHED'}

• Tested it with time module: bpy.context.window.cursor_set("WAIT") time.sleep(5) bpy.context.window.cursor_set("DEFAULT") Code works. What is your issue? – p2or Feb 14 '15 at 17:29
• yes the code works perfectly. my question is this: If I have 10 operators, I have to put this code in each operator? – Logiquefloue Feb 14 '15 at 17:40
• You could probably write a decorator function if you find yourself writing repetitive code like that, but this is more like a stackoverflow general python question then.. – zeffii Feb 14 '15 at 19:52

Using a decorator in an Operator class. Notice the repeating code is defined once in the decorator and any* function which you want to wrap that code around can be decorated with the @mouse_change

import bpy
import time

# declare the decorator
def mouse_change(func):
bpy.context.window.cursor_set("WAIT")
func(*args)
bpy.context.window.cursor_set("DEFAULT")

class SimpleCBOperator(bpy.types.Operator):
bl_idname = "node.some_callback_identifier"
bl_label = "Short Name"

fn_name = bpy.props.StringProperty(default='')

@mouse_change
def dispatch(self, context, type_op):

if type_op == 'some_named_function':
time.sleep( 5 )
print(type_op)

elif type_op == 'some_named_other_function':
time.sleep( 5 )
print(type_op)

def execute(self, context):
self.dispatch(context, self.fn_name)
return {'FINISHED'}

def register():
bpy.utils.register_class(SimpleCBOperator)

def unregister():
bpy.utils.unregister_class(SimpleCBOperator)

if __name__ == "__main__":
register()

# test call
bpy.ops.node.some_callback_identifier(fn_name='some_named_function')


*The way I wrote the decorator function won't let you decorate the execute function.

you would have less code, and arguably more understandable code, by dropping the decorator entirely and going with a dispatch-callback pattern..

class SimpleCBOperator(bpy.types.Operator):
bl_idname = "node.some_callback_identifier"
bl_label = "Short Name"

fn_name = bpy.props.StringProperty(default='')

def dispatch(self, context, type_op):
cursor_set = bpy.context.window.cursor_set
cursor_set("WAIT")

if type_op == 'some_named_function':
pass

elif type_op == 'some_named_other_function':
pass

cursor_set("DEFAULT")

def execute(self, context):
self.dispatch(context, self.fn_name)
return {'FINISHED'}


The drawback of using a single operator 'callback' with an internal dispatch, is that the tooltip wouldn't be unique per fn_name. These are at least a few options to look into.