从右到左的用户界面#

切换文本流和布局

概述#

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

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

文本对齐#

(此适用于TextTextInputTextEdit类型。)

当一个文本项的水平对齐未显式设置时,文本元素自动对齐到文本的自然阅读方向。默认情况下,从左到右的文本(如英语)对齐到文本区域的左侧,而从右到左的文本(如阿拉伯语)对齐到文本区域的右侧。具有空文本的文本元素的对齐方式是从QInputMethod::inputDirection()中获得对齐提示,它基于活动系统地区。

此基于地区的默认对齐方式可以通过设置文本元素的水平对齐属性来覆盖,或者通过启用使用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
}

定位器和视图的布局方向#

(这适用于网格ListViewGridView类型。)

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

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

// 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应用程序的从右到左支持而提供的。它反转了项目锚点位置器模型视图的布局方向,以及QML文本类型的有意文本对齐。

可以为特定的项目启用布局镜像。

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来查询文本的有效视觉对齐。对于锚点,只读的anchors.mirrored属性反映了锚点是否已经被反转。

请注意,使用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(),以确定布局方向。

要为特定区域定义布局方向,请将专门的字符串文字QT_LAYOUT_DIRECTION在QGuiApplication上下文中声明为LTRRTL

首先,在您的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将正确镜像。第二个绑定确保根组件的子项也将遵守镜像。

您可以通过运行编译后的翻译文件来测试布局方向是否按预期工作。

qml myapp.qml -translation myapp.qm

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

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