1
$\begingroup$

I have implemented a ModalTimerOperator, based on the sample in Blender's Python templates. At the moment it can be started, stopped and restarted by buttons (located in a menu added to the Info header for testing purposes). Later it should be started automatically when activating the addon I am working on. Important: The timer is intended to run until Blender is closed.

But now I observed that the timer's cancel() function is called as soon as a *.blend file is loaded, and it stops working therefore (I fear there may be other events doing the same). Putting a return statement into the cancel() function before calling wm.event_timer_remove() does not help.

So my questions are:

  • How can I prevent my timer from being cancelled?
  • Is it possible to restart the timer automatically if cancelled? (My try to restart it from a kind of Python watchdog thread causes Blender to crash as the API documentation's "Gotchas" chapter predicts.)
$\endgroup$
2
$\begingroup$

First such practice as modal operator running in background without user actually starting it from UI or having the ability to end it is bad. For example it will block F8- reload plugins.

Try to use the scene_update callback list in app.handlers instead of modal operator for what you wanna do.

Now also from such callback list you can monitor if some modal operator is or is not running and eventually call it. But again, this is very dirty.

$\endgroup$
  • $\begingroup$ Thank you very much, I tried your approach using a handler which seems much better to me than using a timer. But I run into a serious problem when calling operators in my handler for the scene_update_post event: Blender crashes with "RuntimeError: maximum recursion depth exceeded". The same handler can be called when hooked to the load_pre event without any problems though ... Any ideas? (Because I run out of characters I will add the code in the next comment.) Background: I need the scene_update_post event because I change the view_matrix according to data from my 3D controller hardware. $\endgroup$ – frisee Dec 18 '14 at 11:12
  • $\begingroup$ And here is the code: import bpy class SimpleOperator(bpy.types.Operator): """Tooltip""" bl_idname = "object.simple_operator" bl_label = "Simple Object Operator" def execute(self, context): print("Hello") return {'FINISHED'} bpy.utils.register_class(SimpleOperator) bpy.ops.object.simple_operator() def sceneUpdateHandler(scene): bpy.ops.object.simple_operator() #bpy.app.handlers.scene_update_post.append(sceneUpdateHandler) # <- Blender crashes bpy.app.handlers.load_pre.append(sceneUpdateHandler) # <- works fine $\endgroup$ – frisee Dec 18 '14 at 11:13
  • $\begingroup$ Sorry for the bad formatting; don't know how to make it better in comments ... $\endgroup$ – frisee Dec 18 '14 at 11:21
  • $\begingroup$ That recursion depth is a limitation:( Probably nothing to do about it. The devs don't want non-stop running operators it seems.. $\endgroup$ – Jaroslav Jerryno Novotny Dec 18 '14 at 20:33
  • $\begingroup$ Okay, I have to stick to my timer then. I restart it in my new bpy.app.handlers.load_post handler now, according to your suggestion. Even if it is a dirty trick, it seems to work for me very well. Thanks again! $\endgroup$ – frisee Dec 19 '14 at 9:33

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.