rprospero
rprospero

Reputation: 961

Bi-directional QML binding without loop

The user of my application can click and drag on an image to select a region of interest. I also want a TextField where the user can manually tweak the values, but I've been having trouble getting the bindings to work.

My first attempted looked like

Column {
    property ROI roi
    Label { text: "Minimum X" }
    TextField {id: min_x; text: roi.pointMin.x}
}

This correctly displays the current x coordinate in the text field. However, when I edit the text field, the position isn't updated. I can correct this with the following code.

Column {
    property ROI roi
    Label { text: "Minimum X" }
    TextField {id: min_x; text: roi.pointMin.x}
    Binding {
        target: roi
        property: "pointMin.x"
        value: min_x.text;
    }
}

This correctly establishes that bidirectional binding that updates both when the user draws a new region of interest and when the user updates the via the TextField. However, the log is spammed with messages about the presence of a binding loop. It's very obvious where the binding loop is, but how can I remove it without losing the functionality?

On the off chance that it matters, roi.pointMin is a QPoint.

EDIT: One crucial point that I hadn't mentioned was that I've been trying to remain completely declarative and avoid event handlers. That rules out many other solutions presented on the site, but may be an impossible ask.

Upvotes: 0

Views: 371

Answers (1)

Soheil Armin
Soheil Armin

Reputation: 2795

For this specific purpose you can use textEdited() of the TextField to detect changes from the user input, instead of binding to the text property.

Column {
    property ROI roi
    Label { text: "Minimum X" }
    TextField {
        id: min_x; 
        text: roi.pointMin.x
        onTextEdited: function() {
            roi.pointMin.x = min_x.text
        }
    }
}

Upvotes: 2

Related Questions