QML的ListView在动态删除Item时无法更新spacing

Qt的MVD即model-view-delegate分别启用着数据列表,显示总体视图框架以及数据中的每一项对应的显示视图。这十分经典且毋庸置疑,而且作为view的一种常用实现ListView的spacing属性可以指定项目和项目之间的间隔。

一旦model的数据被准备好,比如model有8项那么ListView就会加载8个delegate,与之对应的spacing就会有7个。如果这时在qml侧做手脚,进行一定的过滤如删除4个delegate,妄图满足某些条件就返回一个无效的delegate,达到只加载4个delegate的效果。虽然delegate可以删除,但是之前加载过的spacing依然是7个而不是3个:

正确的效果应该是:

这也许是Qt不够智能的原生问题,不管我在现在code里面是让loader返回undefined还是null,抑或是让delegate如text的高度为0,visible为false都无法解决上述问题。我的原始code如下:

    Component {
        id: contactDetail
        SLContactDetails {
            id: contactDetails
            currentPageId: pageID
            dataModel: pageDataList
            dataDelegate: Loader {
                sourceComponent: switch (model.type) {
                    case ListItemType.IconInfoItem:
                        return undefined
                    case ListItemType.NoteItem:
                        if (model.value === "") {
                            return undefined
                        } else {
                            return dnItem
                        }
                    case ListItemType.IconMenuItem:
                        if (model.value != "") {
                            addTopopupMenuList(model)
                        }
                        return undefined
                    case ListItemType.TextItem:
                        if (model.value === "") {
                            return undefined
                        } else {
                            return dnItem
                        }
                    default:
                        return undefined
                    }
                Component {
                    id: dnItem
                    SLText {
                        width: Skin.CONTACT_DETAIL_INFO_WIDTH
                        height: Skin.CONTACT_DETAIL_TEXT_HEIGHT
                        elide: Text.ElideRight
                        text: model.value
                        horizontalAlignment: Text.AlignHCenter
                        color: QmlGlobal.colors.ivory
                        font.pixelSize: Skin.CONTACT_DETAIL_TEXT_SIZE
                    }
                }
            }

此问题在 qt - Hide an item (delegate) inside a ListView QML - Stack Overflow 也有提及,他意思是model作为数据来源应该就不发不需要的数据,而不是发给qml让qml去过滤,这个不符合MVD的模型。

只想少改动qml的代码解决问题,也有hack的方法。即设置delegate的height为负数以抵消多余的spacing;或者spacing设为0,让每个delegate自带一个spacing。

当然上述hack的方法可读性也不好,归根结底还是要遵守MVD模型去开发。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值