从右到左的用户界面

切换文本流和布局

概述

本章讨论了为Qt Quick应用程序实现从右到左语言支持的不同方法和可用选项。一些常见的从右到左语言包括阿拉伯语、希伯来语、波斯语和乌尔都语。大多数更改包括确保翻译成从右到左语言的文本正确地对齐到右侧,并且视图、列表和网格中的水平排序内容从右到左正确流动。

在从右到左阅读的语言文化中,人们自然地会从右到左扫描和阅读图形元素和文本。一般的经验法则是,内容(如照片、视频和地图)不会被镜像,但内容的定位(如应用程序布局和视觉元素的流动)会被镜像。例如,按时间顺序显示的照片应从右到左流动,水平滑块的低端范围应位于滑块的右侧,文本行应对齐到可用文本区域的右侧。当视觉元素的位置与内容相关时,不应镜像其位置;例如,当显示位置标记以指示地图上的位置时。此外,还有一些特殊情况您可能需要考虑,即从右到左阅读语言的使用者习惯于从左到右的定位,例如在使用电话中的数字拨号器和音乐播放器中的播放、暂停、倒带和快进按钮时。

文本对齐

(这适用于TextTextInputTextEdit类型。)

当文本项的水平对齐方式未明确设置时,文本元素会自动对齐到文本的自然阅读方向。默认情况下,像英语这样的从左到右的文本会对齐到文本区域的左侧,而像阿拉伯语这样的从右到左的文本会对齐到文本区域的右侧。具有空文本的文本元素的对齐方式取自QInputMethod::inputDirection(),该函数基于当前系统区域设置。

这种基于默认区域设置的对齐方式可以通过为文本元素设置horizontalAlignment属性来覆盖,或者通过使用LayoutMirroring附加属性启用布局镜像,这会导致任何显式的左右水平对齐被镜像。请注意,当LayoutMirroring被设置时,horizontalAlignment属性值保持不变;考虑到镜像的文本元素的有效对齐可以从effectiveHorizontalAlignment属性中读取。

// automatically aligned to the left
Text {
    text: "Phone"
    width: 200
}

// automatically aligned to the right
Text {
    text: "خامل"
    width: 200
}

// aligned to the left
Text {
    text: "خامل"
    horizontalAlignment: Text.AlignLeft
    width: 200
}

// aligned to the right
Text {
    text: "خامل"
    horizontalAlignment: Text.AlignLeft
    LayoutMirroring.enabled: true
    width: 200
}

定位器和视图的布局方向

(这适用于RowGridFlowListViewGridView类型。)

用于水平定位和模型视图的类型具有layoutDirection属性,用于控制布局的水平方向。将layoutDirection设置为Qt.RightToLeft会导致项目从右到左布局。默认情况下,Qt Quick遵循从左到右的布局方向。

水平布局方向也可以通过LayoutMirroring附加属性进行反转。这会导致定位器和视图的有效layoutDirection被镜像。请注意,layoutDirection属性的实际值将保持不变;考虑到镜像的定位器和视图的有效布局方向可以从effectiveLayoutDirection属性中读取。

// by default child items are positioned from left to right
Row {
    Child {}
    Child {}
}

// position child items from right to left
Row {
    layoutDirection: Qt.RightToLeft
    Child {}
    Child {}
}

// position child items from left to right
Row {
    LayoutMirroring.enabled: true
    layoutDirection: Qt.RightToLeft
    Child {}
    Child {}
}

布局镜像

附加属性 LayoutMirroring 是为了方便为现有的从左到右的 Qt Quick 应用程序轻松实现从右到左的支持而提供的。它镜像了 Item anchors 的行为、positionersmodel views 的布局方向,以及 QML 文本类型的显式文本对齐方式。

您可以为特定的Item启用布局镜像:

Item {
    height: 50; width: 150

    LayoutMirroring.enabled: true
    anchors.left: parent.left   // anchor left becomes right

    Row {
        // items flow from left to right (as per default)
        Child {}
        Child {}
        Child {}
    }
}

或者将所有子类型设置为也继承布局方向:

Item {
    height: 50; width: 150

    LayoutMirroring.enabled: true
    LayoutMirroring.childrenInherit: true
    anchors.left: parent.left   // anchor left becomes right

    Row {
        // setting childrenInherit in the parent causes these
        // items to flow from right to left instead
        Child {}
        Child {}
        Child {}
    }
}

以这种方式应用镜像不会改变相关锚点、layoutDirectionhorizontalAlignment 属性的实际值。可以使用单独的只读属性 effectiveLayoutDirection 来查询考虑了镜像的定位器和模型视图的有效布局方向。同样,TextTextInputTextEdit 类型也获得了只读属性 effectiveHorizontalAlignment,用于查询文本的有效视觉对齐方式。

请注意,使用x属性值(而不是锚点或定位器类型)定义的应用程序布局和动画不受LayoutMirroring附加属性的影响。因此,为这些类型的布局添加从右到左的支持可能需要对您的应用程序进行一些代码更改,特别是在依赖锚点和基于x坐标定位的视图中。以下是一种使用LayoutMirroring附加属性将镜像应用于使用x坐标定位的项目的方法:

Rectangle {
    color: "black"
    height: 50; width: 50
    x: mirror(10)
    function mirror(value) {
        return LayoutMirroring.enabled ? (parent.width - width - value) : value;
    }
}

并非所有布局都需要进行镜像处理。有些情况下,视觉类型被放置在屏幕的右侧是为了改善单手使用体验,因为大多数人都是右撇子,而不是因为阅读方向。如果某个子类型不应受到镜像的影响,请将该类型的LayoutMirroring.enabled属性设置为false。

Qt Quick 旨在开发动画流畅的用户界面。在镜像应用程序时,请记住测试动画和过渡是否继续按预期工作。如果您没有资源为应用程序添加从右到左的支持,最好保持应用程序布局左对齐,并确保文本被正确翻译和对齐。

镜像图标

(这适用于ImageBorderImageAnimatedImage类型。)

大多数图像不需要镜像,但一些方向性图标,如箭头,可能需要镜像。这些图标的绘制可以使用专用的mirror属性进行镜像:

Image {
    source: "arrow.png"
    mirror: true
}

默认布局方向

使用Qt.application.layoutDirection属性来查询应用程序的活动布局方向。它继承了QGuiApplication::layoutDirection(),该函数从活动的语言翻译文件中确定布局方向。

要为特定区域设置定义布局方向,请在上下文QGuiApplication中声明专用字符串字面量QT_LAYOUT_DIRECTIONLTRRTL

首先,在你的QML源代码的某个地方引入这行代码:

qsTr("QT_LAYOUT_DIRECTION","QGuiApplication");

然后使用 lupdate 生成翻译源文件。

这将以下声明附加到翻译文件中,您可以在其中输入LTRRTL作为该地区的翻译。

<context>
    <name>QGuiApplication</name>
    <message>
        <location filename="myapp.qml" line="33"/>
        <source>QT_LAYOUT_DIRECTION</source>
        <translation type="unfinished">RTL</translation>
    </message>
</context>

接下来,将以下绑定添加到应用程序的根QML组件中:

LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft
LayoutMirroring.childrenInherit: true

第一个绑定确保在设置从右到左的区域设置时,UI将适当地镜像。第二个绑定确保根组件的子项也将尊重镜像。

您可以通过使用编译后的翻译文件运行您的Qt Quick应用程序来测试布局方向是否按预期工作:

qml myapp.qml -translation myapp.qm

您可以通过调用静态函数QGuiApplication::setLayoutDirection()来测试您的应用程序在从右到左布局方向下的表现:

QGuiApplication app(argc, argv);
app.setLayoutDirection(Qt::RightToLeft);