I tried this

subscribe_to = (bpy.types.ViewLayer, "active_layer_collection")

I also tried these:

subscribe_to = (bpy.types.Context, "collection")
subscribe_to = (bpy.context, "collection")
subscribe_to = (bpy.context.view_layer, "active_layer_collection")

And more, they don't work.

How to be notified when the active collection changes?

Another question: when context.selected_objects changes, get notified.

subscribe_to = (bpy.types.LayerObjects, 'selected')
subscribe_to = (bpy.context, 'selected_objects')

It doesn't work either.

  • 1
    $\begingroup$ msgbus unfortunately often doesn't work. You can use the Application Handler instead, and on every change check if what you're interested in has changed. I show this technique (though not using app handler) here: Driver based on shading types/ change boolean when switching shading types $\endgroup$ Oct 4, 2022 at 15:06
  • 1
    $\begingroup$ Thanks SpaceOutliner.draw_handler_add(update, (), 'WINDOW', 'POST_PIXEL') This works. $\endgroup$
    – Kayon
    Oct 5, 2022 at 4:40
  • $\begingroup$ You can post your own answer to the question for future visitors having a similar problem. $\endgroup$ Oct 5, 2022 at 8:38

1 Answer 1


Finally, I solved the problem in this way.

Thanks for the method provided by Markus von Broady.

import bpy
from bpy.types import SpaceOutliner

def update():
    if bpy.context.area.type != "OUTLINER":

    # update bpy.context.collection
    # update bpy.context.selected_object
    # ...

def register():
    SpaceOutliner.my_handler = SpaceOutliner.draw_handler_add(update, (), 'WINDOW', 'POST_PIXEL')

def unregister():
    SpaceOutliner.draw_handler_remove(SpaceOutliner.my_handler, 'WINDOW')
  • $\begingroup$ It looks like this method is very computationally intensive, because it doesn't check if the collection was changed since the last function call (and the function is called on each mouse cursor draw for example, so quite a lot). Maybe you just didn't show it in your answer, but just in case, you could add on line 3 last_col = None, and then inside update() somewhere early if bpy.context.collection == last_col: return, and below that last_col = bpy.context.collection. $\endgroup$ Oct 5, 2022 at 13:54

You must log in to answer this question.

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