Gather

Description

The Gather object is a PropertyModifier object which gathers references to objects and stores them in a target list. The behaviour of the gather operation is very flexible and can be customized through recursive and combinations of filters such as typeFilter, expressionFilter and nameFilter.

Like other objects, Gather monitors the source object and all of its subobjects for property changes and updates the target automatically.

The most typical use case is to flatten a hierarchical object structure into a list, optionally based on certain criteria.

› Inherits:PropertyModifier

Properties

deferUpdatesWhileDeserializing

This property holds whether to defer and combine updates when many related properties are changed in a row, e.g. when deserializing properties of the source object or one of its child objects. This can improve performance significantly however the list of gathered objects is not up to date until the property updates have been finished.

This property was introduced in InCore 2.0.

› Type:Boolean
› Default:true
› Signal:deferUpdatesWhileDeserializingChanged()
› Attributes:Writable

deferUpdatesWhileRepeatersUpdating

This property holds whether to defer and combine updates while one or multiple children of type Repeater are populating objects.

This property was introduced in InCore 2.0.

› Type:Boolean
› Default:true
› Signal:deferUpdatesWhileRepeatersUpdatingChanged()
› Attributes:Writable

error

This property holds the most recently occurred error or Gather.NoError if no error occurred. If the same error occurs multiple times this property does not change. Use the errorOccurred() signal to detect multiple occurrences of the same error.

› Type:Error
› Signal:errorChanged()
› Attributes:Readonly

errorString

This property holds the current human readable error string corresponding to the current value in the error property. It may include additional information such as failure reasons or locations.

› Type:String
› Signal:errorStringChanged()
› Attributes:Readonly

expressionFilter

This property holds an expression which is used to filter objects. The expression is evaluated for each object and needs to evaluate to true in order to include an object in the target list. The respective object is provided in the item variable. This allows gathering only objects whose properties match certain criteria, e.g. a value above a threshold. See the Gather example for further details.

› Type:<QML expression>
› Signal:expressionFilterChanged()
› Attributes:Writable

nameFilter

This property holds a string or regular expression used to filter objects by name or Object.objectId. The name of each object has to contain the string or match the regular expression to be added to the target list.

› Type:String
› Signal:nameFilterChanged()
› Attributes:Writable

orderBy

This property holds an expression evaluating to a value by which to order the objects before inserting them into the target list. When left blank, the order of the objects is random and non-deterministic. The respective object is provided in the item variable. This also allows specifying the property of a subobject, e.g. item.view.orderIndex to sort DataObject objects by DataObjectView.orderIndex.

› Type:<QML expression>
› Signal:orderByChanged()
› Attributes:Writable, Optional

recursive

This property holds whether to search for objects recursively. When set to false only direct child objects of the source object and objects in list properties of the source object are gathered.

Note

When using Repeaters on list properties of the source object and Repeater.alternativeParent is set the populated objects do not become children of the source object. They therefore are only gathered (as children of the list property) when recursive is set to true.

› Type:Boolean
› Default:true
› Signal:recursiveChanged()
› Attributes:Writable

source

This property holds the source object which to gather objects from.

› Type:Object
› Signal:sourceChanged()
› Attributes:Writable

typeFilter

This property holds a component (QML/object type) which to filter objects. When set the target list contains only objects which either are exactly of the specified object type or inherit from it. This allows gathering e.g. only Measurement objects from a list or tree of DataObject objects.

› Type:<QML component>
› Signal:typeFilterChanged()
› Attributes:Writable

Signals

errorOccurred()

This signal is emitted whenever an error has occurred, regardless of whether the error property has changed or not. In contrast to the change notification signal of the error property this signal is also emitted several times if a certain error occurs several times in succession.

Enumerations

Error

This enumeration describes all errors which can occur in Gather objects. The most recently occurred error is stored in the error property.

Name Value Description
Gather.NoError 0 No error occurred or was detected.
Gather.InvalidPropertyType 1 Gather not supported for non-list property “”.
Gather.NotWritableError 2 Gather not supported for readonly property “”.
Gather.InvalidObjectTypeError 3 Can’t add incompatible object to property “”.
Gather.ObjectInsertionError 4 Error inserting object to property “”.
Gather.FilterExpressionError 5 Error while evaluating filter expression: <Unknown File>: .

Example

import InCore.Foundation 2.0

Application {

    property var dynMeas1;
    property var dynMeas2;

    ObjectArray {
        id: dataObjects

        // group with statically populated objects
        DataObjectGroup {
            DataObject { id: meas1; data: -10 }
            DateTime { id: dateTime }
            Measurement { id: meas2; data: 2 }
            property var meas3: Measurement { id: meas3; data: 3 }
        }

        // group with dynamically populated objects
        MeasurementGroup {
            onCompleted: {
                Qt.createQmlObject('import InCore.Foundation 2.5; DataObject { id: dynDO1; data: 10 }', this);
                Qt.createQmlObject('import InCore.Foundation 2.5; DataObject { id: dynDO2; data: 5.2 }', this);
                dynMeas1 = Qt.createQmlObject('import InCore.Foundation 2.5; Measurement { id: dynMeas1; data: 10 }', this);
                dynMeas2 = Qt.createQmlObject('import InCore.Foundation 2.5; Measurement { id: dynMeas2; data: 20 }', dynMeas1);
                // destroy object again so we should observe a decrease in number of gathered objects
                dynMeas2.destroy();
            }
        }
    }

    // gather all objects recursively
    List {
        Gather on items {
            source: dataObjects
        }
        onItemsChanged: console.log("Total object count:", items.length)

    }

    // gather all Temperature objects
    List {
        Gather on items {
            source: dataObjects
            typeFilter: Measurement { }
        }
        onItemsChanged: console.log("Measurement object count:", items.length)
        // log any changes of the gathered temperatures
        onDataChanged: console.log("Measurement", index, "changed to", items[index].data)
    }

    // gather all dynamically created objects
    List {
        Gather on items {
            source: dataObjects
            nameFilter: "dyn.*"
        }
        onItemsChanged: console.log("Number of dynamic objects:", items.length)
    }

    // gather all measurements with value above 10
    List {
        Gather on items {
            source: dataObjects
            typeFilter: Measurement { }
            expressionFilter: item.data > 10
        }
        onItemsChanged: console.log("Number of measurements with value above 10:", items.length)
    }

    // sort measurements by value
    List {
        Gather on items {
            source: dataObjects
            typeFilter: Measurement { }
            orderBy: item.data
        }
        onItemsChanged: {
            var values = []
            for( var key in items )
            {
                values.push(items[key].data);
            }
            console.log("Sorted measurement values:", values)
        }
    }

    // increase measurement value dynamically to observe changes in the list above
    Timer {
        running: true
        interval: 1000
        onTriggered: {
            dynMeas1.data++;
        }
    }
}