Let's say I have two 3D Viewports opened in Blender. I have an Add-on that shows an operator in the sidebar menu. Now if I press the operator I want another viewport window to go into Camera view using python (not the one where I pressed the operator).

I guess that can be done by moving the cursor into the other window, but I was wondering if there is a less "wonky" way?


I wrote a basic Addon, that includes @Crantisz approach (which makes total sense to me) but it doesn't work as intended. It toggles the camera view in the viewport where the operator is pressed, not the other ones. When I use this approach within the python console it works though.

To reproduce:

Open blender with two Viewports and click the operator.

    bl_info = {
    "name" : "Toggle View",
    "author" : "Timmethy",
    "description" : "Toggel Camera View in different Viewport",
    "blender" : (3, 0, 0),
    "version" : (0, 0, 1),
    "location" : "",
    "warning" : "",
    "category" : "3D View"
import bpy

def camview(context):
    for a in context.screen.areas:
        if a != context.area and a.type == 'VIEW_3D':
            targetarea = a
    override = {'area': targetarea}

class SWITCHCAM_OT_operator(bpy.types.Operator):
    bl_label = "Switch Camera"
    bl_idname = "wm.cam"
    def draw(self, context):
        layout = self.layout
    def execute(self, context):  

        if bpy.data.objects['Camera']:
            bpy.context.view_layer.objects.active = bpy.data.objects['Camera']
        return {'FINISHED'}

class SWITCHCAM_PT_panel(bpy.types.Panel):
    bl_label = "Toggle Camera"
    bl_idname = "SWITCHCAM_PT_panel"
    bl_space_type = "VIEW_3D"
    bl_region_type = 'UI'
    bl_category = "Toggle Camera"
    bl_context = "objectmode"
    def draw(self, context):
        scene = context.scene
        layout = self.layout

classes = [SWITCHCAM_PT_panel, SWITCHCAM_OT_operator]

def register():
    for cls in classes:

def unregister():
    for cls in classes:

1 Answer 1


It can be done by override context in function. Since the only important data for setting viewport is area you should pass only area into context.

def main(context):
    # I don't know how you want to select different area 
    # let's say it is any view 3D but not current one
    for a in context.screen.areas:
        if a != context.area and a.type == 'VIEW_3D':
            targetarea = a
    override = {'area': targetarea}

Well... I don't know why it doesn't work. Do this without ops:

for a in context.screen.areas:
    if (a != context.area) and (a.type == 'VIEW_3D'):
        for space in a.spaces:
            if space.type == "VIEW_3D":
space.region_3d.view_perspective = 'CAMERA'
  • $\begingroup$ The parameter override get's ignored when the function is run with an operator. It works when run as a script or directly in the console. $\endgroup$
    – Timmethy
    Commented Mar 31, 2022 at 14:36
  • $\begingroup$ If you pass wrong area, for example text editor it will raise the error $\endgroup$
    – Crantisz
    Commented Mar 31, 2022 at 14:59
  • $\begingroup$ Well but it can't since you checked with a.type =='VIEW_3D', right? Anyhow, your second aproach works, thank you very much! $\endgroup$
    – Timmethy
    Commented Mar 31, 2022 at 15:04

You must log in to answer this question.

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