I've written a script takes the start and end values of a VSE strip, and copies those values to the NLA strip of a selected object (effectively syncing the NLA strip with the VSE strip). The script works well enough, however, I have to click the 'Run Scrript' button every time I move the VSE Strip.

How would I go about making it so that when I move the VSE strip, the NLA strip moves automatically as well?

I've researched using handlers and the def update functions but nothing has worked for me (including drivers).

Below is the script I've worked up. I'll attach the .Blend I use with it as well

import bpy

targetName = 'My_Strip'

for vsestrip in bpy.context.scene.sequence_editor.sequences_all:
    if targetName in vsestrip.name:
        vsestrip.select = True
        strip.select = False

vsestart = bpy.context.scene.sequence_editor.sequences_all["My_Strip"].frame_start

for obj in bpy.context.selected_objects:           
    obj.animation_data.nla_tracks[0].strips[0].frame_start = vsestart
    obj.animation_data.nla_tracks[0].strips[0].frame_end = vsestart            
    obj.animation_data.nla_tracks[0].strips[0].scale = 1


1 Answer 1


somewhat important note: this way if doing it should work, but its really hacky and might be unstable or interfere with other parts of blender (im using blender 2.80).

step one

create a new file in C:\Users\--Username--\AppData\Roaming\Blender Foundation\Blender\2.80\scripts\addons or the eqivalent path in other operating systems, its important that the file ends with .py copy the code below and paste into the new file.

step two

open blender and go to Preferences>addons search for test and enable the test addon, save user preferences, open a new file (in blender) or close and reopen blender, if you have a sequence selected and press the left mouse button you should get a message in the console that says "The Script goes here" (open it by going to Window>Toggle System Console).

from bpy.app.handlers import persistent
import bpy

bl_info = {
    "name": "test",
    "author": "Syler",
    "version": (0, 0, 0, 1),
    "description": "test",
    "blender": (2, 80, 0),
    "category": "Object"

def load_handler(dummy):
    print("Load Handler:", "test")

def script():
    print('The Script goes here')

class TestModal(bpy.types.Operator):
    bl_idname = "test.modal"
    bl_label = "test Modal"
    bl_options = {"REGISTER", "UNDO", "INTERNAL"}

    def modal(self, context, event):
        #note: using context.area.type to check weather the event got called in the video sequencer doesn't work, don't know why.

        if event.type == 'LEFTMOUSE' and event.value == 'RELEASE':
            if context.selected_sequences != []:

        return {'PASS_THROUGH'}

    def invoke(self, context, event):
        return {'RUNNING_MODAL'}

classes = (

def register():

    from bpy.utils import register_class
    for cls in classes:


def unregister():

    from bpy.utils import unregister_class
    for cls in classes:

the way this works is the addon gets registered, then when a file gets loaded it calls the TestModal Class, which checks the input for the left mouse button, when you also have a sequence selected then it calls the script def.

  • $\begingroup$ It is hacky, but it works well enough. Thanks! I'll still be researching the best way to do this but this is a good start (and the best one so far). $\endgroup$
    – Dassie
    Commented May 17, 2019 at 18:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .