QML Text属性width、implicitWidth、contentWidth更新时序
创始人
2025-05-29 07:21:46
0

为了实现一种较复杂的Row, 该Row在整个屏幕是居中的, Row里面有2个Text A、B和一个分隔符(图片). B的长度取决于A的长度以及三个部件的总长度. 总长度是720而Text A优先显示, 则B可显示长度为720-A长度-分隔符,Text B显示不下则显示“...”. 大概效果是(第一行):

Text B显示得下效果是:

为了实现出上述需求, QML代码如下:

    Row {anchors.horizontalCenter: parent.horizontalCenterspacing: Skin.MARGIN_8SLText {id: subLabelwidth: Math.min(implicitWidth, Skin.CALL_INFO_WIDTH)visible: text != ""}SLSeparatorDot {anchors.verticalCenter: parent.verticalCentervisible: subLabel.visible && hgLabel.visible}SLText {id: hgLabelwidth: getHgWidth(subLabel.implicitWidth, hgLabel.implicitWidth)elide: Text.ElideRightonImplicitWidthChanged: {console.log("!!!hgLabel onImplicitWidthChanged:"+implicitWidth);}onContentWidthChanged: {console.log("!!!hgLabel onContentWidthChanged:"+contentWidth);}onWidthChanged: {console.log("!!!hgLabel onWidthChanged:"+width);}function getHgWidth(subImplicitWidth, hgImplicitWidth) {var hgWidth = 0;console.log("!!!getHgWidth0 subImplicitWidth:"+subImplicitWidth+",hgImplicitWidth:"+hgImplicitWidth);if (hgImplicitWidth > 0 && subImplicitWidth > 0) {hgWidth = Math.min(hgImplicitWidth, Skin.CALL_INFO_WIDTH - subImplicitWidth - Skin.SEPARATOR_DOT_WIDTH - Skin.MARGIN_8 * 2)}else if (hgImplicitWidth > 0) {hgWidth = Math.min(hgImplicitWidth, Skin.CALL_INFO_WIDTH)}return hgWidth;}}}SLText {id: demoanchors.horizontalCenter: parent.horizontalCentertext: "xxxxxxxx"onImplicitWidthChanged: {console.log("!!!demo onImplicitWidthChanged:"+implicitWidth);}onContentWidthChanged: {console.log("!!!demo onContentWidthChanged:"+contentWidth);}onWidthChanged: {console.log("!!!demo onWidthChanged:"+width);}}

由于项目中的Text内容是动态加载的,时序和固定内容的Text有些许区别. 我特意加了一个普通Text作为对比,并在每个要关注的signal的响应的slot(onXxxChanged)中打出log去观察时序:

8104 DEB Mar 16 16:00:53.586844 (25414-25414) guiapp-!!!demo onWidthChanged:101.5
8105 DEB Mar 16 16:00:53.586912 (25414-25414) guiapp-!!!demo onImplicitWidthChanged:101.5
8106 DEB Mar 16 16:00:53.586966 (25414-25414) guiapp-!!!demo onContentWidthChanged:101.5
8107 DEB Mar 16 16:00:53.587004 (25414-25414) guiapp-!!!demo onImplicitWidthChanged:101.58103 DEB Mar 16 16:00:53.585190 (25414-25414) guiapp-!!!getHgWidth0 subImplicitWidth:0,hgImplicitWidth:0
8128 DEB Mar 16 16:00:53.637086 (25414-25414) guiapp-!!!getHgWidth0 subImplicitWidth:172.6875,hgImplicitWidth:0
8129 DEB Mar 16 16:00:53.637427 (25414-25414) guiapp-!!!hgLabel onImplicitWidthChanged:201.203125
8130 DEB Mar 16 16:00:53.637477 (25414-25414) guiapp-!!!getHgWidth0 subImplicitWidth:172.6875,hgImplicitWidth:201.203125
8131 DEB Mar 16 16:00:53.637527 (25414-25414) guiapp-!!!hgLabel onWidthChanged:201.203125
8132 DEB Mar 16 16:00:53.637640 (25414-25414) guiapp-!!!hgLabel onContentWidthChanged:201.203125

可以看到,

对于动态内容Text, width被getHgWidth绑定, 故function一定先调用, 不论implicitWidth和contentWidth是否为0. 一旦有text动态更新,先变化的属性是implicitWidth, 这将trigger function再次调用,这将导致width更新, 而最后更新的是contentWidth.

对于固定内容Text, witdh未设置, 从log来看width先变化, 然后是implicitWidth最后是contentWidth. 一些资料对于Text的实际文字长度选用contentWidth可能是有问题的. 在此我们得知,如果要尽早得知Text的实际文字长度的更新应该使用implicitWidth.

说句题外话,我之前getHgWidth想用Text A和Text B的visible属性来作为function参数来更新witdh,但发现虽然每次visible更新但是implicitWidth/contentWidth可能为0(我一旦在onVisible里面打log去print implicitWidth/contentWidth则函数体内implicitWidth/contentWidth就被更新了). 可见QML内部这些属性的更新有自己的时序, 而且getHgWidth函数体内即便有implicitWidth和contentWidth但拿到的值并不是最新的. 因此尝试使用implicitWidth/contentWidth作为参数去 trigger function, 结果是达到预期的. 因此推断QML中function是由参数而非函数体内变量去trigger的.

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...