【问题标题】:How to listen for property collection size changes如何监听属性集合大小的变化
【发布时间】:2018-08-14 05:55:58
【问题描述】:

我想根据属性的集合大小自动显示/隐藏视图,代码如下:

QtObject {
    property var controlWindow: Window {
        property var collection: []

        signal sigAddElement(var element)
        onSigAddElement: {
            collection.push(element)
        }

        signal sigEraseAllElements()
        onSigEraseAllElements: {
            collection.length = 0
        }

        onCollectionChanged: {
            console.log("collection.len = " + collection.length)
        }

        Rectangle {
            id: autoHidableView
            visible: collection.length != 0
        }
    }
}

但是autoHidableViewvisible 属性在启动时只评估一次,并且不再评估
onCollectionChanged 处理程序永远不会被调用,这是可以理解的,因为集合对象本身保持不变
那么是否可以监听集合的大小更改事件?

【问题讨论】:

  • 我在visiblevisible 属性上收到collection is not defined 的警告@,所以这可能是它不起作用的原因。另外,你为什么把它包装在一个 QtObject 中?
  • @Amfasis,这是一个遗留代码,我删除了所有不相关的部分,但我不确定 QtObjectWindow 是否相关,所以我保存了它们。您是否弄清楚为什么会收到 undefined 警告?
  • 我没有查看undefined,但在引用controlWindow.collection.count 时可能会起作用?
  • @Amfasis,这只是一个模拟代码,不需要它是可编译的。但这个错误似乎很有趣:)

标签: qt qml


【解决方案1】:

问题是您使用property var collection: [] 创建的javascript 数组没有任何信号(onCollectionChanged 确实是您为其分配新集合的时候)。你最好使用 ListModel:

QtObject {
    property var controlWindow: Window {

        ListModel {
            id: collection
        }

        signal sigAddElement(var element)
        onSigAddElement: {
            collection.append(element)
        }

        signal sigEraseAllElements()
        onSigEraseAllElements: {
            collection.clear()
        }

        Rectangle {
            id: autoHidableView
            visible: collection.count > 0
        }
    }
}

请注意,您需要将push 更改为append

【讨论】:

  • 感谢您的回答,请将collection.length = 0 替换为collection.clear() 以便成为可行的解决方案
  • 感谢您发现这一点,我主要专注于添加 ;-)
【解决方案2】:

只听数组长度是不够的。 见var QML Basic Type

请务必注意,分配给 var 属性的 JavaScript 对象的常规属性的更改不会触发访问它们的绑定更新。

将数组分配给 var 时的行为相同。只有使用全新的对象/数组重新分配属性时,才会重新评估绑定。

您有两种方法可以让您的绑定监听集合长度的变化:

  • 重新分配整个数组:

    onSigAddElement: {
        collection = collection.concat(element)
    }
    // ...
    onSigEraseAllElements: {
        collection = []
    }
    
  • 手动触发变化信号:

    onSigAddElement: {
        collection.push(element)
        collectionChanged()
    }
    // ...
    onSigEraseAllElements: {
        collection.length = 0
        collectionChanged()
    }
    

【讨论】:

  • 感谢您的回答,但第一个选项不会强制重新评估 visibleautoHidableView 属性。第二个是我想简化的初始选项
  • 我成功测试了这两个选项,您确定您的 Rectangle 实际上不可见而是被其他组件隐藏和/或没有宽度/高度?在 Rectangle 上打印onVisibleChanged时是否有日志?
  • 我只测试了onSigEraseAllElements处理程序,我会调查一下
  • 是的,我还必须在测试时设置宽度+高度+颜色;-) 从QtObject展开它旁边
猜你喜欢
  • 2012-03-30
  • 2020-05-18
  • 2017-05-16
  • 1970-01-01
  • 2011-06-13
  • 1970-01-01
  • 2023-02-08
  • 1970-01-01
相关资源
最近更新 更多