<bpy.msgbus>模块提供了一种在Blender内部组件之间通信的方法。消息总线是一种分布式事件系统,允许不同组件之间以异步方式传递消息,这种方式既简单又高效。
使用<bpy.msgbus>模块,可以使用<bpy.msgbus.subscribe_routine>方法注册消息。以下是此方法的语法:
bpy.msgbus.subscribe_routine(
key:typing.Hashable,
obj:typing.Any,
prop:str,
args:typing.Tuple[typing.Any, ...]=(),
notify:typing.Callable[[typing.Any, typing.Any], Any]=None
) -> BpyMessageBusSubscriber
参数说明:
key
(typing.Hashable) - 消息的唯一标识符,可以是任何Hashable类型的对象。通常使用字符串。obj
(typing.Any) - 包含属性的对象,发布消息时将它作为参数传递。prop
(str) - 字符串表示的属性名称。将在obj
中注入消息的值。args
(typing.Tuple[typing.Any, ...]) - 关键字参数的元组。notify
(typing.Callable[[typing.Any, typing.Any], Any]) - 将在订阅的消息发布时调用的可调用对象。import bpy
def my_callback():
print("Object was updated!")
subscriber = bpy.msgbus.subscribe_routine(
key='Object_updated',
obj=bpy.context.object,
prop='update_tag',
args=(),
notify=my_callback,
)
在这个例子中,当<bpy.context.object>更新的时候,就会触发"Object_updated"消息。当订阅消息时,也可以传递其他参数,其中<bpy.types.PropertyGroup>中的任何属性都可以作为消息的传递参数。
要取消所注册的用户定义函数的订阅,请使用订阅器的.remove()
方法。
# Unsubscribe the routine
subscriber.remove()
使用`<bpy.msgbus>模块可以监听系统各组件之间的消息,比如监听<a href="https://docs.blender.org/manual/en/latest/render/workflows/command_line.html">命令行</a>的输出。
例如,如果你想监听命令行输出,并将所有标准输出链接到特定对象的自定义属性
import bpy
import sys
def print_to_object_callback(channel, string):
# dummy function to set context object active
new_area = bpy.context.area.copy()
new_area.type = 'CONSOLE'
bpy.context.screen.areas.append(new_area)
bpy.ops.console.clear()
bpy.context.scene.my_custom_property = string.strip()
# Replace sys.stdout with our message handler
sys.stdout = bpy.types.Object
bpy.msgbus.subscribe_routine(
# Send message when a line of text is printed
key=(bpy.types.Object, "stdout"),
# Send the object as arg[0], and the message as arg[1:]
obj=bpy.context.object,
prop="my_custom_property",
args=(),
notify=print_to_object_callback,
)
在上述代码中,<b>print_to_object_callback()</b>函数作为订阅消息函数的回调函数被引用,这里除了我们自己定义的,其他所有的控制台输出都将被重定向到的我们将要指定的回调函数中来。
使用<bpy.msgbus.publish>方法可以简单地向消息总线和订阅程序发布消息。它允许发送任何Hashable对象的消息,通常使用字符串。
bpy.msgbus.publish(
key='object_updated',
data=bpy.context.object,
)
在这个例子里,当触发'object_updated'事件时,bpy.context.object
对象就会被作为参数传递。
带有关键字参数的消息可以如下所示:
bpy.msgbus.publish(
key='custom_message',
data=bpy.context.object,
any_value=42,
some_tuple=(1, 2, 3),
)
注意,我们使用data参数来发送对象作为消息数据,并设置通信协议时的标识符。键值对的值将作为消息的其他参数(保留data作为第一个参数)小心使用键值。Blender中的许多对象只更新一次,之后可能将其删除,并可能在进入帧更新等回调中接收到更新。<b>如果在正在发送消息的回调中修改data参数,则不会将此修改提交,而会引发异常</b>。如果需要将此传递,请使用复杂类型或其他对象作为参数。
这个模块为创造匿名、协作式系统提供了基础,并在与插件开发工作流一起使用时非常强大。
对于插件开发,消息总线是一个有用的工具,可以在不创建控制台输出、交互式接口或使用节点编辑器的情况下传递信息 / 数据。使用消息总线的应用程序需要一些学习,并可以使用它来改善技术上复杂的问题,如高级分布式任务分配、数据分析流的构建等。