0
$\begingroup$

A quick bit of context: I am interested in having a startup script that among other things, sets the frame start and frame end. Ideally this would be in a startup script over a startup file as is it makes it easier to see the variables in codes, and potentially let them be determined by an environment variable in the future

While setting the frame start and frame end is easy, it's trying to have the Dope Sheet and Graph Editor (which by default needs to be switched into from the Dope Sheet) to frame to the new range.

Initially I had tried using the old context override method - bpy.context.copy(). This will loop through all workspaces and frame the Dope Sheet Editor

import bpy
c_override = bpy.context.copy()

for my_screen in bpy.data.screens:
    for my_area in my_screen.areas:

        if(my_area.type == 'DOPESHEET_EDITOR'):            
            for my_region in my_area.regions:

                if my_region.type == 'WINDOW':                    
                    c_override['screen'] = my_screen
                    c_override['area'] = my_area
                    c_override['region'] = my_region
                    bpy.ops.action.view_all(c_override)

However if I want to frame the Dope Sheet Editor, then switch to the Graph Editor, frame all, and the switch back to the Dope Sheet Editor so my Animation Editor is back to how it started, I would get "context is incorrect".

import bpy
c_override = bpy.context.copy()

for my_screen in bpy.data.screens:

    for my_area in my_screen.areas:
        if(my_area.type == 'DOPESHEET_EDITOR'):
            
            for my_region in my_area.regions:
                if my_region.type == 'WINDOW':
                    
                    c_override['screen'] = my_screen
                    c_override['area'] = my_area
                    c_override['region'] = my_region

                    bpy.ops.action.view_all(c_override)
                    
                    my_area.type = 'GRAPH_EDITOR'
                    bpy.ops.graph.view_all(c_override)

                    c_area.type = 'DOPESHEET_EDITOR'

I had seen in this post A comprehensive list of operator overrides that the way of creating a context override is different now in Blender 3.2, using C.temp_override() instead of C.copy()

I had got this working with the current workspace

import bpy

for my_area in bpy.context.window.screen.areas:
    
    if my_area.type == 'DOPESHEET_EDITOR':        
        for my_region in my_area.regions:
            
            if my_region.type == 'WINDOW':                
                with bpy.context.temp_override(
                    window = bpy.context.window,
                    area = my_area,
                    region = my_region,
                ):
                    bpy.ops.action.view_all()
            
    if my_area.type == 'GRAPH_EDITOR':        
        for my_region in my_area.regions:
            
            if my_region.type == 'WINDOW':                
                with bpy.context.temp_override(
                    window = bpy.context.window,
                    area = my_area,
                    region = my_region,
                ):
                    bpy.ops.graph.view_all()

However if I want this to run over all workspaces, when it gets to the Animation workspace if errors "TypeError: Area not found in screen"

import bpy

for my_screen in bpy.data.screens:
    for my_area in my_screen.areas:
        
        if my_area.type == 'DOPESHEET_EDITOR':
            for my_region in my_area.regions:
                if my_region.type == 'WINDOW':
                    with bpy.context.temp_override(
                        window = bpy.context.window,
                        #screen = my_screen,
                        area = my_area,
                        region = my_region,
                    ):
                        bpy.ops.action.view_all()

I wondered if anyone had any pointers to try and get this working?

Update 1 ===============================================================

It seems to be specifically changing the screens that causes issues. For example, any one of these loops run fine on their own, but one after the other fails

# frame dopesheet and switch to graph editor
for screen in bpy.data.screens:
    for area in screen.areas:
        if area.type == 'DOPESHEET_EDITOR':
            for region in area.regions:
                if region.type == 'WINDOW':
                    ctx = bpy.context.copy()
                    ctx['screen'] = screen
                    ctx['area'] = area
                    ctx['region'] = region
                    bpy.ops.action.view_all(ctx)
                    area.type = 'GRAPH_EDITOR'

# frame graph editor and return to dopesheet
for screen in bpy.data.screens:
    for area in screen.areas:
        if area.type == 'GRAPH_EDITOR':
            for region in area.regions:
                if region.type == 'WINDOW':
                    ctx = bpy.context.copy()
                    ctx['screen'] = screen
                    ctx['area'] = area
                    ctx['region'] = region
                    bpy.ops.graph.view_all(ctx)
                    area.type = 'DOPESHEET_EDITOR'
  File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\modules\bpy\ops.py", line 113, in __call__
    ret = _op_call(self.idname_py(), C_dict, kw, C_exec, C_undo)
RuntimeError: Operator bpy.ops.graph.view_all.poll() failed, context is incorrect

However if I just run on the current screen, it works fine

# frame dopesheet and switch to graph editor
for area in bpy.context.screen.areas:
        if area.type == 'DOPESHEET_EDITOR':
            for region in area.regions:
                if region.type == 'WINDOW':
                    ctx = bpy.context.copy()
                    ctx['screen'] = bpy.context.screen
                    ctx['area'] = area
                    ctx['region'] = region
                    bpy.ops.action.view_all(ctx)
                    area.type = 'GRAPH_EDITOR'

# frame graph editor and return to dopesheet
for area in bpy.context.screen.areas:
        if area.type == 'GRAPH_EDITOR':
            for region in area.regions:
                if region.type == 'WINDOW':
                    ctx = bpy.context.copy()
                    ctx['screen'] = bpy.context.screen
                    ctx['area'] = area
                    ctx['region'] = region
                    bpy.ops.graph.view_all(ctx)
                    area.type = 'DOPESHEET_EDITOR'
$\endgroup$
4
  • $\begingroup$ Can you paste the entire error traceback into your answer please? $\endgroup$ Commented Jul 6, 2022 at 17:49
  • $\begingroup$ The second snippet (using the old context copy method) gave me this error python Error: Python: Traceback (most recent call last): File "\Text", line 19, in <module> File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\modules\bpy\ops.py", line 113, in __call__ ret = _op_call(self.idname_py(), C_dict, kw, C_exec, C_undo) RuntimeError: Operator bpy.ops.graph.view_all.poll() failed, context is incorrect $\endgroup$
    – luithne
    Commented Jul 8, 2022 at 9:34
  • 1
    $\begingroup$ the fourth snippet using the newer content temp override gave my this error python Traceback (most recent call last): File "C:\Program Files\Blender Foundation\Blender 3.2\3.2\scripts\modules\bpy_types.py", line 864, in draw_ls def draw_ls(self, context): KeyboardInterrupt Error: Python: Traceback (most recent call last): File "\Text", line 9, in <module> TypeError: Area not found in screen $\endgroup$
    – luithne
    Commented Jul 8, 2022 at 9:35
  • $\begingroup$ The issue it displays is TypeError, because the problem with the new temp_override is that it overrides window and area, but not screen. bpy.context.screen won't get overridden meaning temp_override will search for the area in the current screen and not Animation or other. $\endgroup$
    – kemplerart
    Commented Jul 14, 2022 at 15:20

2 Answers 2

1
$\begingroup$

Although context.copy() is depracated, it is still working.
Rewrote your code, gives no errors on execute

import bpy

for screen in bpy.data.screens:
    for area in screen.areas:
        if area.ui_type == 'DOPESHEET':
            override = bpy.context.copy()
            override['area'] = area
            override['screen'] = screen
            bpy.ops.action.view_all(override)
$\endgroup$
1
  • $\begingroup$ I just tried this snippet, but found it only works if a region is added to the context override However although this works fine, if I am looping through all screens and I change the editor type such as "area.type = 'GRAPH_EDITOR'" during the loop and then run another loop again it fails (see updated post for better explanation) $\endgroup$
    – luithne
    Commented Jul 21, 2022 at 11:02
0
$\begingroup$

I believe this was fixed with this commit: https://projects.blender.org/blender/blender/commit/6af92e13607bde4cdaccba0f280e7a5219725cbf

This snippet works in Blender 4.2:

    # Only run on a new file / startup file
    if bpy.data.filepath != '':
        return

    log.info(f"Callback: Frame Animation Editor Views")

    # Dopesheet Editor
    for screen in bpy.data.screens:
        for area in screen.areas:
            if area.type not in ['DOPESHEET_EDITOR']:
                continue

            for region in area.regions:
                if region.type != 'WINDOW':
                    continue
                
                ctx = bpy.context.copy()
                ctx['screen'] = screen
                ctx['area'] = area
                ctx['region'] = region

                with bpy.context.temp_override(**ctx):
                    bpy.ops.action.view_all()
                    area.type = 'GRAPH_EDITOR'

    # Graph Editor
    for screen in bpy.data.screens:
        for area in screen.areas:
            if area.type not in ['GRAPH_EDITOR']:
                continue

            for region in area.regions:
                if region.type != 'WINDOW':
                    continue
                
                ctx = bpy.context.copy()
                ctx['screen'] = screen
                ctx['area'] = area
                ctx['region'] = region

                with bpy.context.temp_override(**ctx):
                    bpy.ops.graph.view_all()
                    area.type = 'DOPESHEET_EDITOR'
    
    return
```
$\endgroup$

You must log in to answer this question.

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