Qt、QML多语言机制核心讲解

例如 ListView 模型model 的文本数据多语言

在开发过程中,经常遇到 QML的 ListView,其中 model 属性里面字段需要多语言
只需要在引用处添加,语言改变触发函数,即可
本例 context: Util.lang(qsTr(tabName))
其中 Util.lang() 函数是语言改变自动触发的JS函数

原理:多语言本质是字符替换,只要查找到对应字符替换即可

lupdate 只是识别 qsTr() 函数,然后进行字符替换 。lupdate不做编译或者运行语法校验

例如
以下写法是错误的,但是这段错误的代码是用于生成ts文件进行字符替换的,生成ts文件之后再去掉 Util.lang() 函数,还原正确的代码。当替换好字符串发布qm文件经过Qt程序加载,运行时,执行到context: Util.lang(qsTr(tabName))引用处,Qt多语言机制到qm文件(此时已经加载到程序内存中)查找对应的字符串,进行替换

错误代码(用于生成ts文件):

        ListModel {
                    ListElement { tabName: Util.lang(qsTr("模式")); tabIndex: ScreenManager.ModeScreen }
                    ListElement { tabName: Util.lang(qsTr("状态")); tabIndex: ScreenManager.StatusScreen }
                    ListElement { tabName: Util.lang(qsTr("媒体")); tabIndex:  ScreenManager.MediaScreen}
                    //ListElement { tabName: "导航"; tabIndex: 3 }
                   // ListElement { tabName: "影像"; tabIndex: 3 }
                    ListElement { tabName: Util.lang(qsTr("轨迹")); tabIndex: ScreenManager.TrackLineScreen }
                    ListElement { tabName: Util.lang(qsTr("保养")); tabIndex: ScreenManager.MaintainScreen }
                    ListElement { tabName: Util.lang(qsTr("设置")); tabIndex: ScreenManager.SystemScreen }
                    ListElement { tabName: Util.lang(qsTr("车辆设置")); tabIndex: ScreenManager.JeepSettings }
           }

正确代码:

     Item {
            width: 138 * 3 + 6 
            height: 60

            ListView {
                id: tabView

                spacing: 3
                clip: true
                anchors.fill: parent
                orientation: ListView.Horizontal
                cacheBuffer: 2000
                snapMode: ListView.SnapOneItem
                highlightRangeMode: ListView.ApplyRange
                currentIndex: _screenManager.currentScreen - ScreenManager.MIN_Screen

                delegate:
                    Widgets.TitleItem {
                    context: Util.lang(qsTr(tabName))
                    selected: tabIndex === _screenManager.currentScreen
                }
                model:
                ListModel {
                    ListElement { tabName: "模式"; tabIndex: ScreenManager.ModeScreen }
                    ListElement { tabName: "状态"; tabIndex: ScreenManager.StatusScreen }
                    ListElement { tabName: "媒体"; tabIndex:  ScreenManager.MediaScreen}
                    //ListElement { tabName: "导航"; tabIndex: 3 }
                   // ListElement { tabName: "影像"; tabIndex: 3 }
                    ListElement { tabName: "轨迹"; tabIndex: ScreenManager.TrackLineScreen }
                    ListElement { tabName: "保养"; tabIndex: ScreenManager.MaintainScreen }
                    ListElement { tabName: "设置"; tabIndex: ScreenManager.SystemScreen }
                    ListElement { tabName: "车辆设置"; tabIndex: ScreenManager.JeepSettings }
                }

            }
        }

所以生成TS文件之后,可以在调用字符串处,调用多语言触发函数,当程序执行时,在调用文本处触发语言改变函数Util.lang(qsTr())即可

这样生成TS文件也行, 保留调用处context: Util.lang(qsTr(tabName))

ListModel 不加qsTr(),即不在此处生成TS文件

                ListModel {
                    ListElement { tabName: "模式"; tabIndex: ScreenManager.ModeScreen }
                    ListElement {tabName: "状态"; tabIndex: ScreenManager.StatusScreen }
                    ListElement {tabName: "媒体"; tabIndex:  ScreenManager.MediaScreen}
                    //ListElement { tabName: "导航"; tabIndex: 3 }
                   // ListElement { tabName: "影像"; tabIndex: 3 }
                    ListElement {tabName: "轨迹"; tabIndex: ScreenManager.TrackLineScreen }
                    ListElement {tabName: "保养"; tabIndex: ScreenManager.MaintainScreen }
                    ListElement {tabName: "设置"; tabIndex: ScreenManager.SystemScreen }
                    ListElement {tabName: "车辆设置"; tabIndex: ScreenManager.JeepSettings }
                }

在这里生成TS文件,在qml文件里面添加自定义代码纯文本,生成完TS文件后删除

       Text{
            text:Util.lang(qsTr("模式"))
        }
        Text{
            text:Util.lang(qsTr("状态"))
        }

        Text{
            text:Util.lang(qsTr("媒体"))
        }

        Text{
            text:Util.lang(qsTr("轨迹"))
        }

        Text{
            text:Util.lang(qsTr("保养"))
        }

        Text{
            text:Util.lang(qsTr("设置"))
        }

        Text{
            text:Util.lang(qsTr("车辆设置"))
        }

还有更高级的

a.qml 包含一下代码

                ListModel {
                    ListElement { tabName: "模式"; tabIndex: ScreenManager.ModeScreen }
                    ListElement {tabName: "状态"; tabIndex: ScreenManager.StatusScreen }
                    ListElement {tabName: "媒体"; tabIndex:  ScreenManager.MediaScreen}
                    //ListElement { tabName: "导航"; tabIndex: 3 }
                   // ListElement { tabName: "影像"; tabIndex: 3 }
                    ListElement {tabName: "轨迹"; tabIndex: ScreenManager.TrackLineScreen }
                    ListElement {tabName: "保养"; tabIndex: ScreenManager.MaintainScreen }
                    ListElement {tabName: "设置"; tabIndex: ScreenManager.SystemScreen }
                    ListElement {tabName: "车辆设置"; tabIndex: ScreenManager.JeepSettings }
                }

在其它目录新建 a.qml文件(一定要保证qml文件名相同,否则Qt程序无法查找对应字符替换)
新建 a.qml文件,生成TS文件后删除:然后TS发布qm文件,用QT程序加载,这样也行

       Text{
            text:Util.lang(qsTr("模式"))
        }
        Text{
            text:Util.lang(qsTr("状态"))
        }

        Text{
            text:Util.lang(qsTr("媒体"))
        }

        Text{
            text:Util.lang(qsTr("轨迹"))
        }

        Text{
            text:Util.lang(qsTr("保养"))
        }

        Text{
            text:Util.lang(qsTr("设置"))
        }

        Text{
            text:Util.lang(qsTr("车辆设置"))
        }

经过以上分析,大家应该很明白了吧,QT/QML 多语言机制

你可能感兴趣的:(QT/QML)