How to change the active object in 2.80

Many operators act from selected objects to the active object, e.g. the parenting operator bpy.ops.object.parent_set. To use it in Python I want to change the active object to the presumed parent. The code to make the object ob active in 2.79 is simply:

context.scene.objects.active = ob

However, this does not work in 2.80 because Scene.objects does not have an active attribute. So my question is, how to change the active object in 2.80?

Scene.objects does not have a link attribute either, but in 2.80 we apparently have to link an object into a collection rather than into a scene. So the 2.79 code

context.scene.objects.link(ob)

corresponds to

context.view_layer.collections.active.collection.objects.link(ob)

But Collection.objects does not have an active attribute, so that does not help in changing the active object.

Hello, here are a few stuff :

to set the active object :
bpy.context.view_layer.objects.active = ob

an alternative to context.view_layer.collections.active.collection.objects.link(ob) :
bpy.context.scene.collection.objects.link(ob)
Here you link object to the scene ‘master collection’ , it’s not in some other collection ,
it will be at the root of the scene in the outliner

Another way :
col = bpy.data.collections[“my collection”]
col.objects.link (ob)

And , another way that I use to set parents without using bpy.ops :
par = bpy.context.scene.objects[“Camera”]
ob = bpy.context.scene.objects[“Cube”]
mat = ob.matrix_world.copy()

ob.parent = par
ob.matrix_world = mat

Even if it’s more lines of code, it’s generally better not to use bpy.ops when possible. Here you don’t need to do selection whatsoever and it’s less context sensitive.
But if bpy.ops work it’s not a crime to use it.

4 Likes

Thank you for very useful info.

N00b so forgive my ignorance: this seems counter intuitive to how I’ve used Python in the past, and I’m getting errors relating to ob not being defined, even when I replace it with the name of an object being used in my file.
Do I have to set OB equal to something elsewhere?

object assignment isn’t counter intuitive at all… you might say it’s the entire backbone of Python.
chances are, since you’re using code from a post that’s two years old, the example is out of date and no longer works. In 2.8 there is no context.scene.objects.active anymore, so you’re probably not getting an error about ‘ob’ not being defined, but scene.objects not having an attribute called ‘active’. The correct 2.8 syntax is:
context.view_layer.objects.active = obj

1 Like