1

This is a possible duplicate of my previous question, but the answers didn't help, so question remains the same. How do I write a code that starts playing animation, and stops playing it in 30 sec? I'm working in blender 2.79 and 2.80. Please give me an example of working code, that's really important for me now.

cxnt
  • 397
  • 1
  • 5
  • 27
  • 1
    If you are referring to https://blender.stackexchange.com/questions/146163/python-timer-is-not-working-for-me-in-blender it wasn't working for you on a version of blender that doesn't have bpy.app.timers I can see no reason why passing screen to the timer and overriding context wouldn't work, as used (similarly for a different op needing different context members) in link I posted in comments. Did you attempt to get app timers working, or simply jump to this new question? The site works much better if you make an attempt, rather than "post me working code, and I'll tell you"... – batFINGER Jul 25 '19 at 09:10
  • 1
    ... if it works. On checking I realize I mistakenly pasted a circular link to question , and have adjusted and answered, and posted correct link in answer. Please point out things like wrong link to sort this out much earlier. – batFINGER Jul 25 '19 at 09:41

2 Answers2

3

Modal timer template

Blender comes with a modal timer in its templates. Text Editor > Templates > Python > Operator Modal Timer Here is the timer for 2.8 converted to start playing when operator pressed, and stop after 30 seconds.

This part

self._timer = wm.event_timer_add(1, window=context.window)

creates a 'TIMER' event every second (the 1 designates 1 second, the original has 0.1 or a tenth of a second)

When 30 of these are counted (30 seconds) the animation is stopped.

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
    count = 0

    def modal(self, context, event):
        if event.type in {'ESC'} or self.count > 30:
            self.cancel(context)
            return {'CANCELLED'}

        if event.type == 'TIMER':
            self.count += 1


        return {'PASS_THROUGH'}

    def execute(self, context):
        wm = context.window_manager
        # start animating
        bpy.ops.screen.animation_play()
        self._timer = wm.event_timer_add(1, window=context.window)
        self.count = 0
        wm.modal_handler_add(self)
        return {'RUNNING_MODAL'}

    def cancel(self, context):
        bpy.ops.screen.animation_cancel(restore_frame=False)


        wm = context.window_manager
        wm.event_timer_remove(self._timer)


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()
batFINGER
  • 84,216
  • 10
  • 108
  • 233
  • I realized it was my mistake, Ive been putting this code to python console, which doesnt work. And when I put it to text editor it perfectly works. Thank you so much!!!!!!!!!!!! – cxnt Jul 25 '19 at 09:49
2

Found an answer On Blender Artists

import bpy
def stop_playback(scene):
    if scene.frame_current == 30:
        bpy.ops.screen.animation_cancel(restore_frame=False)

# add one of these functions to frame_change_pre handler:
bpy.app.handlers.frame_change_pre.append(stop_playback)
#start animation
bpy.ops.screen.animation_play()
rob
  • 1,718
  • 1
  • 16
  • 21