Is it possible to run a script every few seconds or so, while letting the interface update in the meantime?
How can I do this?
Is it possible to run a script every few seconds or so, while letting the interface update in the meantime?
How can I do this?
See the Operator Modal Timer template in the Text Editor:
import bpy
class ModalTimerOperator(bpy.types.Operator):
"""Operator which runs its self from a timer"""
bl_idname = "wm.modal_timer_operator"
bl_label = "Modal Timer Operator"
_timer = None
def modal(self, context, event):
if event.type == 'ESC':
return self.cancel(context)
if event.type == 'TIMER':
# change theme color, silly!
color = context.user_preferences.themes[0].view_3d.space.gradients.high_gradient
color.s = 1.0
color.h += 0.01
return {'PASS_THROUGH'}
def execute(self, context):
self._timer = context.window_manager.event_timer_add(0.1, context.window)
context.window_manager.modal_handler_add(self)
return {'RUNNING_MODAL'}
def cancel(self, context):
context.window_manager.event_timer_remove(self._timer)
return {'CANCELLED'}
def register():
bpy.utils.register_class(ModalTimerOperator)
def unregister():
bpy.utils.unregister_class(ModalTimerOperator)
if __name__ == "__main__":
register()
# test call
bpy.ops.wm.modal_timer_operator()
You can specify the interval for the 'TIMER' event, but note that all active timers will be caught (there is no way to distinguish them).
The timer class also comes with some handy attributes:
if event.type == 'TIMER':
print (self._timer.time_duration) # elapsed time since the operator call
print (self._timer.time_delta) # elapsed time since the last step
...
Beware of using threads, they can crash Blender.
in blender 2.80 you can do this: (for blender 2.7 I don't know)
def timer_call_fnc():
print('called')
return 1.0 # call every second
bpy.app.timers .register( timer_call_fnc )
timer_call_fnc() # make first call
# unregister later:
#bpy.app.timers .unregister( timer_call_fnc )
more info: blender 2.80 timer api
note:
"You should never modify Blender DATA at arbitrary points in time in separate threads. "
for addons you might have to make the timer and handler persistent. example:
# blender 2.8 example
# persistent timer
#
from bpy.app.handlers import persistent
@persistent # do not discard, when file changes
def timer_fired():
# do stuff
return 0.5 # seconds
@persistent
def handler_load_post():
if not bpy.app.timers .is_registered( timer_fired ):
bpy.app.timers .register( timer_fired, first_interval=1.0, persistent=True )
def my_init():
bpy.app.handlers .load_post .append( handler_load_post )