D-Bus适配器中声明槽
D-Bus适配器中的槽声明与常规的公共槽类似,但它们的参数必须遵循某些规则(详细信息请参见Qt D-Bus类型系统)。不遵循这些规则或不是公共的槽将无法通过D-Bus访问。
槽可以有一个参数类型为const QDBusMessage &
,该参数必须出现在输入参数列表的最后,在所有输出参数之前。如果存在该参数,它将初始化为正在处理的当前消息的副本,这允许被调用者获取有关调用者信息,例如其连接名称。
槽可以是三种类型之一
- 异步
- 仅输入
- 输入和输出
异步槽
异步槽通常不向调用者返回任何回复。因此,它们不能接受任何输出参数。在大多数情况下,在槽的第一行运行时,调用函数已经恢复工作。
然而,槽不得依赖于该行为。调度和消息分派问题可能会改变槽的运行顺序。打算与调用者同步的代码应提供自己的同步方法。
异步槽在方法签名中以关键字Q_NOREPLY标记,在void
返回类型和槽名称之前。在D-Bus Complex Ping Pong示例中,quit()
槽是这种类型的示例。
仅输入槽
仅输入槽是接受通过值或通过常量引用传递的参数的常规槽。然而,与异步槽不同,调用者通常在完成调用者之前才会继续操作。因此,非异步槽不应阻塞或应在其文档中明确表示可能会阻塞。
仅输入槽在其签名中没有特殊标记,除了它们仅接受通过值或通过常量引用传递的参数。可选地,槽可以接受一个作为最后一个参数的QDBusMessage参数,可用于执行对方法调用消息的附加分析。
输入和输出槽
类似于只输入接口 slot,输入输出接口 slot 是调用方等待回复的。但与只输入的相比,这个回复将包含数据。可能输出数据的 slot 可能包含非常量引用,也可能返回一个值。然而,输出参数必须位于参数列表的末尾,并且不能有输入参数混入。可选地,可以在输入和输出参数之间出现一个 QDBusMessage 参数。
自动回复
方法回复是由 Qt D-Bus 实现根据输出参数的内容(如果有的话)自动生成的。slot 不需要担心构造合适的 QDBusMessage 对象并通过连接发送它们。
然而,这样做是有可能的。如果 slot 发现它需要发送特殊的回复甚至错误,它可以通过在 QDBusMessage 参数上使用 QDBusMessage::createReply() 或 QDBusMessage::createErrorReply() 并通过 QDBusConnection::send() 发送来做到这一点。Qt D-Bus 实现如果 slot 这样做了,将不会生成任何回复。
警告:调用方放置一个方法调用并等待回复时,它只会等待一定的时间。打算执行很长时间的槽应该在该文档中指出这一点,以便调用方设置较高的超时时间。
延迟回复
在某些情况下,被调用的 slot 可能无法立即处理请求。这通常是涉及 I/O 或网络操作的情况,这些操作可能会阻塞。
如果情况如此,slot 应该将控制权交回应用程序的主循环以避免冻结用户界面,稍后再继续处理。为了实现这一点,它应该使用输入参数列表末尾的额外 QDBusMessage
参数并请求延迟回复。
我们通过编写一个槽来做到这一点,这个槽将请求数据存储在持久结构中,并使用 QDBusMessage::setDelayedReply(true) 通知调用方响应将在稍后发送。
struct RequestData { QString request; QString processedData; QDBusMessage reply; }; QString processRequest(const QString &request, const QDBusMessage &message) { RequestData *data = new RequestData; data->request = request; message.setDelayedReply(true); data->reply = message.createReply(); appendRequest(data); return QString(); }
在这种情况下,返回值是不重要的;我们返回一个任意值以满足编译器。
当请求被处理并且有回复可用时,应该使用获得的 QDBusMessage
对象发送回复。在我们的示例中,回复代码可能如下所示
void sendReply(RequestData *data) { // data->processedData has been initialized with the request's reply QDBusMessage &reply = data->reply; // send the reply over D-Bus: reply << data->processedData; QDBusConnection::sessionBus().send(reply); // dispose of the transaction data delete data; }
如示例所示,当设置延迟回复时,Qt D-Bus 会忽略槽的返回值。这些值仅用于在与远程应用程序通信时确定槽的签名,或者如果槽中的代码决定不使用延迟回复。
延迟回复本身就是通过在原始消息上调用 QDBusMessage::reply() 从 Qt D-Bus 请求的。然后,向调用方发送回复成为调用代码的责任。
警告:调用方放置一个方法调用并等待回复时,它只会等待一定的时间。打算执行很长时间的槽应该在该文档中指出这一点,以便调用方设置较高的超时时间。
另请参阅:使用 Qt D-Bus 适配器,在 D-Bus 适配器中声明信号,Qt D-Bus 类型系统,QDBusConnection 和 QDBusMessage。
© 2024 The Qt Company Ltd. 本文档中包含的贡献资料归属其各自所有者。提供的文档根据自由软件基金会发布的GNU自由文档许可 versión 1.3 进行许可。Qt及其相关商标是芬兰及全球其他国家的The Qt Company Ltd.的商标。所有其他商标归其各自所有者所有。