本页内容

IVI Compositor

IVI Compositor 是一个演示如何使用IviApplication 扩展的示例。

简介

本示例演示了如何在 Wayland 显示服务器(也称为 Wayland 合成器)中使用IviApplication 壳扩展。

有关使用 Qt 创建 Qt Wayland Compositor ,请参阅“Minimal Qml”示例。

该协议

IviApplication 是一个专门为车载信息娱乐系统设计的shell 扩展。

这是一个极简协议,仅提供以下功能:

  1. 客户端可通过IVI-id 进行自我识别。
  2. 服务器可请求客户端调整自身大小。
标识号

在典型的IviApplication 配置中,会有一组预定义的应用程序可以连接到服务器。由于这些应用程序在系统设计阶段就已经确定,因此可以为其分配硬编码的编号以进行识别。鉴于客户端和服务器事先就这些编号达成一致,可以在ID编号中嵌入特定含义。

例如,如果某个客户端将自身标识为导航应用程序,服务器便可识别这一点,并为其窗口分配屏幕中央的大片区域;而将自身标识为时钟的应用程序,则可能会被分配到屏幕边缘较小的区域。

默认情况下,Qt 应用程序会将其系统 PID(“进程 ID”)作为IVI-id 进行广播。客户端可以在连接到服务器之前,通过在环境中设置 `QT_IVI_SURFACE_ID ` 来覆盖此默认行为。

示例

一个Qt Wayland Compositor 可能同时支持多个shell扩展,但IVICompositor示例仅支持IviApplication 协议。这意味着客户端必须也支持此shell扩展才能连接到服务器。

示例中的合成器窗口水平分为两部分:左侧区域专用于ID为“1337”的特定应用程序,右侧区域则用于所有其他应用程序。

合成器窗口水平分割,左侧区域用于应用程序 ID 为“1337”的应用程序,右侧区域用于其他应用程序

创建布局

窗口的布局是在WaylandOutput 内部创建的。这通常对应于合成器可用的物理屏幕。如果像IVICompositor示例中那样创建单个WaylandOutput ,它通常对应于主屏幕。

WaylandOutput {
    sizeFollowsWindow: true
    window: Window {
        width: 1024
        height: 768
        visible: true
        Rectangle {
            id: leftArea
            width: parent.width / 2
            height: parent.height
            anchors.left: parent.left
            color: "cornflowerblue"
            Text {
                anchors.centerIn: parent
                text: "Ivi surface with id 1337"
            }
        }
        Rectangle {
            id: rightArea
            width: parent.width / 2
            height: parent.height
            anchors.right: parent.right
            color: "burlywood"
            Text {
                anchors.centerIn: parent
                text: "Other surfaces"
            }
        }
    }
}

该代码为屏幕创建一个WaylandOutput ,并在此基础上创建一个Window,作为所有合成器内容的顶级容器。在此窗口内,它创建了两个矩形,这些矩形将作为应用程序连接时的容器。

连接客户端

如果未进行额外配置,Qt 应用程序将使用与自身进程 ID 相同的IVI-id进行连接。例如,如果我们运行另一个 Qt 示例应用程序,并使用-platform wayland ,那么只要其 ID 不同于“1337”,该应用程序就会被分配到布局的右侧。

右侧带有标签和文本输入框的排版窗口

但是,如果我们在启动示例之前将QT_IVI_SURFACE_ID 环境变量设置为“1337”,该应用程序将被分配到布局的左侧。

左侧带有标签和文本输入框的排版窗口

当客户端连接到IVIApplication 接口时,它将发出iviSurfaceCreated 信号。此时将处理应用程序界面的定位。

IviApplication {
    onIviSurfaceCreated: (iviSurface) =>  {
        var surfaceArea = iviSurface.iviId === 1337 ? leftArea : rightArea;
        var item = chromeComponent.createObject(surfaceArea, { "shellSurface": iviSurface } );
        item.handleResized();
    }
}

iviSurfaceCreated 信号接收一个IviSurface 参数,该参数可用于获取客户端的ID。随后,合成器会为该表面创建一个ShellSurfaceItem (如chromeComponent 所定义)。ShellSurfaceItem 是用于将shell表面放置到Qt Quick 场景中的类,在所有Qt Wayland Compositor 示例中你都会看到相同的模式。

使IVICompositor 示例与众不同之处在于,它会检查传入壳面(shell surface)的iviId 属性,并根据该属性值决定ShellSurfaceItem 的父对象。如果 ID 等于“1337”,则将其作为leftArea 的子对象;否则,则将其置于rightArea 中。

ShellSurfaceItem 的实现通过在尺寸发生变化时通知客户端来处理尺寸调整(当合成器在桌面风格的窗口系统中运行且其窗口被调整大小时,可能会发生这种情况)。

onWidthChanged: handleResized()
onHeightChanged: handleResized()
function handleResized() {
    if (width > 0 && height > 0)
        shellSurface.sendConfigure(Qt.size(width, height));
}

sendConfigure() 方法在IviSurface 中定义,并将向客户端发送一个事件。客户端将收到包含新尺寸的调整大小事件,从而可以重新布局其内容。

如果多个应用程序连接到布局中的同一区域,它们将按照常规的 `Qt Quick ` 排序规则进行堆叠。虽然没有内置的机制来关闭应用程序或管理状态,但这可以通过普通的 `Qt Quick ` 代码轻松实现。

示例项目 @ code.qt.io

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.