- Qt 6.10
- Qt Quick
- QML Types
- Qt.labs.synchronizer
- Synchronizer
- Qt 6.10.0 Reference Documentation

# Synchronizer QML Type

Synchronizes values between two or more properties. More...

Import Statement: | `import Qt.labs.synchronizer`
Since: | Qt 6.10

- List of all members, including inherited members

## Properties

- sourceObject : QtObject
- sourceProperty : string
- targetObject : QtObject
- targetProperty : string

## Signals

- valueBounced(QtObject object, string property)
- valueIgnored(QtObject object, string property)

## Detailed Description

A Synchronizer object binds two or more properties together so that a change to any one of them automatically updates all others. While doing so, none of the bindings on any of the properties are broken. You can use Synchronizer if the direction of data flow between two properties is not pre-determined. For example, a TextInput may be initialized with a model value but should also update the model value when editing is finished.

Note: The input elements provided by Qt Quick and Qt Quick Controls solve this problem by providing user interaction signals separate from value change signals and hiding the value assignments in C++ code. You don't need Synchronizer for their internals. However, it may still be useful when connecting a control to a model.

Consider the following example.

## Without Synchronizer

     // MyCustomTextInput.qml
     Item {
         property string text
         function append(characters: string) { text += characters }
         [...]
     }

You may be inclined to populate the `text` property from a model and update the model when the `textChanged` signal is received.

     // Does not work!
     Item {
         id: root
         property string model: "lorem ipsum"
         MyCustomTextInput {
             text: root.model
             onTextChanged: root.model = text
         }
     }

This does not work. When the `append` function is called, the `text` property is modified, and the binding that updates it from the `model` property is broken. The next time the `model` is updated independently `text` is not updated anymore.

To solve this, you can omit the binding altogether and use only signals for updating both properties. This way you would need to give up the convenience of bindings.

Or, you can use Synchronizer.

## With Synchronizer

     Item {
         id: root
         property string model: "lorem ipsum"
         MyCustomTextInput {
             Synchronizer on text {
                 property alias source: root.model
             }
         }
     }

Synchronizer makes sure that whenever either the model or the text change, the other one is updated.

You can specify properties to be synchronized in several ways:

- Using the `on` syntax
- Populating the `sourceObject` and `sourceProperty` properties
- Populating the `targetObject` and `targetProperty` properties
- Creating aliases in the scope of the synchronizer

The following example synchronizes four different properties, exercising all the different options:

     Item {
         id: root
         property string model: "lorem ipsum"

         MyCustomTextInput {
             Synchronizer on text {
                 sourceObject: other
                 sourceProperty: "text"

                 targetObject: root.children[0]
                 targetProperty: "objectName"

                 property alias source: root.model
                 property alias another: root.objectName
             }
         }

         MyCustomTextInput {
             id: other
         }
     }

Optionally, Synchronizer will perform an initial synchronization:

- If one of the aliases is called `source`, then it will be used to initialize the other properties.
- Otherwise, if the values assigned to sourceObject and sourceProperty denote a property, that property will be used as source for initial synchronization.
- Otherwise, if the `on` syntax is used, the property on which the Synchronizer is created that way is used as source for initial synchronization.
- Otherwise no initial synchronization is performed. Only when one of the properties changes the others will be updated.

Synchronizer automatically de-bounces. While it is synchronizing using a given value as the source, it does not accept further updates from one of the properties expected to be the target of the update. Such behavior would otherwise easily lead to infinite update loops. Synchronizer uses the valueBounced signal to notify about this condition. Furthermore, it detects properties that silently refuse an update and emits the valueIgnored signal for them. Silence, in this context, is determined by the lack of a change signal after calling the setter for the given property.

If the properties to be synchronized are of different types, the usual QML type coercions are applied.

## Property Documentation

sourceObject : QtObject

This property holds the sourceObject part of the sourceObject/sourceProperty pair that together can specify one of the properties Synchronizer will synchronize.

sourceProperty : string

This sourceProperty holds the sourceProperty part of the sourceObject/sourceProperty pair that together can specify one of the properties Synchronizer will synchronize.

targetObject : QtObject

This property holds the targetObject part of the targetObject/targetProperty pair that together can specify one of the properties Synchronizer will synchronize.

targetProperty : string

This targetProperty holds the targetProperty part of the targetObject/targetProperty pair that together can specify one of the properties Synchronizer will synchronize.

## Signal Documentation

valueBounced(QtObject object, string property)

This signal is emitted if the property of the object refused an attempt to set its value as part of the synchronization and produced a different value in response. Such bounced values are ignored and don't trigger another round of synchronization.

Note: The corresponding handler is `onValueBounced`.

valueIgnored(QtObject object, string property)

This signal is emitted if property of the object did not respond to an attempt to set its value as part of the synchronization.

Note: The corresponding handler is `onValueIgnored`.