Qt/Qml 实现字符串动态计算

当我们要显示包含变量的文字时,在 Qml 里面怎么实现?下面我们就提供一种方法。

功能需求

可配置的文字能够满足很多需求,如果我们能够让可配置的文字中包含变量,并且支持动态的计算,那就让程序的迭代变得更加灵活了。

比如在出错提示场景,我们考虑将出错时,程序的一些相关状态一同展示出来。

Failed to move object ${canvas.movingObject}, it's now position at (${canvas.movingObject.x}, ${canvas.movingObject.y}).

这段文字可能来源于一个错误码描述文件,也可能来源于服务后台配置的文字。

随着使用迭代,错误文字得到了逐步完善,甚至里面的变量也会新增或者替换成其他的。

与 Qt 语言翻译配合,我们可以只更新翻译(.qm)文件,就可以不用修改代码、升级应用。

Qt 语言翻译提供基于字符串 format 的变量文字方案,但是需要预埋固定数量的参数,并且需要代码配置,没有本文的方案灵活。

实现方案

如果直接通过 Qml 代码实现,上面的字符串,可能会这样写:

Text {
    text: "Failed to move object " + canvas.movingObject + 
        ", it's now position at (" + canvas.movingObject.x + ", " + canvas.movingObject.y + ")."
}

显然这代码写出来就固定了,不能灵活的修改。但是如果我们动态生成这段代码呢?那我告诉你,在 Qml 中,这是可行的。

你可能会先想到 eval,通过 Qt.eval 方法,可以执行动态的代码,显然计算出一个字符串不在话下。但是假如上面的文字在显示的时候,对象还在不停移动,其 x、y 还在变化,要跟踪其变化,通过 eval 就不太好做了。

我们的方案是这样的:

首先,动态生成一个 Qml 对象,就像上面的 Text 那样,其有一个属性是这个动态计算的字符串。

然后,将目标属性与该对象的这个字符串属性绑定,这样就能跟踪 x、y 这些变量的变化了。

最后,我们还要记得及时释放动态创建的对象,以免引起内存泄露。

DynamicString.qml

QtObject {

    property string input
    property string output
    property var object

    onInputChanged: {
       var lastObject = object
       var script = File.content("qrc:/DynamicString.qml")
       script = script.replace("output", "output: " + input.replace(/\$\{([\w()\.]+)\}/g, "\"+($1)+\""))
       object = Qt.createQmlObject(script, this, "DynamicString.qml")
       output = Qt.binding(function() { return object.output })
       if (lastObject) lastObject.destroy()
    }
}

Test.qml

DynamicString {
    id: errorDynamicString
    property var canvas: parent // The variable used by error strings
    input: errorString
}

Text {
    text: errorDynamicString.output
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fighting Horse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值