Owner can be any python object.+
Using example here https://developer.blender.org/P563 can use the simple python object class to instance a handle.
handle = object()
Can also use
handle = 4
handle = set()
Simple example throws callback when context object name is changed. Running in text editor (main thread) the handle is lost. A quick workaround is to save it to the driver namespace.
import bpy
handle = object()
# all branches below work
if 1:
# To get some properties we need to prevent them being coerced into native Py types.
subscribe_to = bpy.context.object.path_resolve("name", False)
elif 0:
subscribe_to = bpy.context.object.location
else:
# all object locations
subscribe_to = bpy.types.Object, "location"
def notify_test(*args):
print("Notify changed!", args)
bpy.msgbus.subscribe_rna(
key=subscribe_to,
owner=handle,
args=(1, 2, 3),
notify=notify_test,
)
# In general we won't need to explicitly publish, nevertheless - support it.
bpy.msgbus.publish_rna(key=subscribe_to)
bpy.app.driver_namespace["handle"] = handle
# ... to clear
# bpy.msgbus.clear_by_owner(handle)
To clear the callback via python console
>>> bpy.msgbus.clear_by_owner(
clear_by_owner(owner)
.. function:: clear_by_owner(owner)
Clear all subscribers using this owner.
>>> bpy.msgbus.clear_by_owner(bpy.app.driver_namespace['handle'])
If an immutable type like int is used (eg handle = 4 can clear from console with
bpy.msgbus.clear_by_owner(4)
but not for a dict handle = {}, possible the hassle in question code when setting the scene ID property.
In an addon can define the handle globally and remove in the unregister method, as it has the addon's module scope.
handle = object()
def register():
# set up a callback with owner = handle
def unregister():
bpy.msgbus.clear_by_owner(handle)