4

I tried this

subscribe_to = (bpy.types.ViewLayer, "active_layer_collection")
bpy.msgbus.subscribe_rna(
    key=subscribe_to,
    owner=bpy,
    args=(None,),
    notify=update,
)

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.

Kayon
  • 61
  • 3

1 Answers1

2

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": return

# 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')

Kayon
  • 61
  • 3
  • 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. – Markus von Broady Oct 05 '22 at 13:54