Qt远程对象副本#

描述了副本的概念以及它作为代理对象是如何工作的。 .. _replica: PySide6.QtRemoteObjects.QRemoteObjectReplica 的一个代理对象("replica")与它所复制的源的 QObject 具有大约相同的 API。另外还有一些属性和信号,使检测副本初始化或失去与源对象的连接成为可能。还有一些其他差异,尤其是源对象上的一些常量属性在副本上不能是常量。该值在副本实例化时是不可知的;只有当副本初始化后才会知道。有关更多信息,请参阅远程对象交互

编译后的副本是一个基于 PySide6.QtRemoteObjects.QRemoteObjectReplica 的类型,其派生类定义由 repc 编译器自动生成。当您使用或 qmake 变量运行 repc 编译器时,这使生成成为构建过程的一部分。尽管只生成一个头文件,但它是一个完整的类型。没有公共构造函数,因此您需要使用

PySide6.QtRemoteObjects.QRemoteObjectDynamicReplica 可以在运行时生成。为此,您需要调用 acquireDynamic(),将源名称(一个 QString)作为参数传递。动态副本从C ++中更易于使用,但不需要编译。动态副本不支持初始化属性值,或直到它们初始化后才支持内省。

这两种创建副本方式之间的重要区别在于副本初始化之前的行为。由于动态副本只有在初始化后才获得metaObject,因此在初始化之前基本上没有API——没有属性,也没有可以连接到插槽的信号。

由于编译副本的metaObjects是在编译时创建的,因此副本实例化时其API也可用。您甚至可以在模板文件中为属性提供默认值,这些值将在副本使用源当前值初始化之前被使用。

副本初始化#

主节点将与其连接的每个节点共享它托管源列表。当源被添加到或从列表中删除时,此主机发送更新。通过这种方式,连接的节点将始终知道它可以连接到哪些源。对特定源的改变只会传播到拥有该源副本的节点。因此,这避免了不必要的网络流量。

当一个节点获得已知源的副本时,它会向主机节点发送对该源的请求。在收到此请求后,主机创建一个包含该源所有属性当前值的响应包。如果请求的副本是 动态的 ,响应包将包括该源的API定义。从那时起,副本的节点将被包括在接收该源变更的连接列表中。

如果某个副本已实例化,但其节点未连接到托管请求源的主机节点,或者该对象位于主机节点进程中,但未为QObject启用共享/远程通信,则副本仍将被创建,但保持未初始化状态。

如果在稍后的时间节点通知副本可以从连接的节点获取请求的源,则在此时它将请求该源并开始初始化过程。

如果与主机节点的连接丢失,副本将变为无效状态。它将尝试重新连接,并在连接恢复时重新初始化,这确保所有属性都是最新的。

副本所有权#

获取方法返回节点实例化的副本QObject的指针。节点无法知道副本的预期寿命。因此,当副本不再需要时,调用程序负责删除它。

您可以实例化同一副本的多个副本。来自单个节点的相同源的副本将共享一个用于处理网络通信的私有数据成员。这意味着多个副本实例不会引入额外的网络流量,尽管会有一些额外的处理开销。未能删除副本将防止此私有对象的引用计数达到0,并在调用程序退出之前造成不必要的网络通信。因此,建议使用QScopedPointer或QSharedPointer帮助跟踪副本的生存期。