2016-08-04 2 views
3

При изучении QML я наткнулся на проблему, что у меня есть свойства, которые зависят друг от друга.Двунаправленное связывание взаимно зависимых свойств в QML

E.g. пользователь может установить значение с помощью ползунка или ввести его с текстовым вводом.
При перемещении ползунка текст в текстовой строке должен быть обновлен, когда при вводе значения в текстовой строке необходимо скорректировать положение ползунка.

Теперь у меня есть два свойства: x-значение ползунка и текст в текстовой строке. Мне нужно преобразовать их в один формат (например: проценты) и обновить их наоборот. Настройка двух привязок приведет к циклу привязки, что, вероятно, не очень хорошо.

Я думаю, это очень распространенная проблема, поэтому я уверен, что для ее решения существует «золотой стандарт». Однако я не могу найти подходящее решение.

Единственный способ, который приходит мне на ум, - не использовать привязки вообще, а обрабатывать сигналы, чтобы одно из значений изменилось вручную (если я не могу перезаписать установщик в C++).
Это все, что вы можете сделать?

Добрый день!
-m-

EDIT: Теперь я попробовал его с условным привязкой значения ползунка к процентному значению.

Объект handle является маркером на слайдере, handleArea прилагается к нему MouseArea, что позволяет перетаскивать.

Binding { 
    target: root 
    property: 'percent' 
    value: handle.x/handleBar.width 
    when: handleArea.drag.active 
} 

Binding { 
    target: handle 
    property: 'x' 
    value: root.percent * handleBar.width 
    when: !handleArea.drag.active 
} 

Это работает. Но это хороший стиль?

ответ

3

Я бы сделал одно свойство, которое будет хранить взаимное значение. Когда пользователь вводит текст или перемещает слайдер, он будет использовать функцию для обновления взаимного значения. Они также прислушаются к изменению стоимости и приспосабливают свое значение к ней.

Вот рабочий пример

import QtQuick 2.5 
import QtQuick.Window 2.2 
import QtQuick.Controls 1.4 

Window { 
    id: window 
    visible: true 
    width: 400 
    height: 80 
    title: "Mutual value test" 

    property double mutualValue: 0 
    function setMutualValue(value) 
    { 
     if (typeof(value) === "string") 
     { 
      value = value.replace(",", "."); 
      value = parseFloat(value) 
     } 
     mutualValue = value 
    } 

    TextInput { 
     width: 200 
     height: 40 
     validator: DoubleValidator {} 
     onEditingFinished: 
     { 
      focus = false 
      setMutualValue(text) 
     } 
     onFocusChanged: 
     { 
      if (text === inputHelp && focus) 
       text = "" 
     } 
     property alias mutualValue: window.mutualValue 
     onMutualValueChanged: setValue(mutualValue) 
     property string inputHelp 
     color: (text === inputHelp && !focus ? "grey" : "black") 
     function setValue(mutualValue) 
     { 
      inputHelp = mutualValue.toFixed(3) 
      text = inputHelp 
     } 
    } 

    Slider { 
     x: 200 
     width: 200 
     height: 40 
     onValueChanged: setMutualValue(value) 
     property alias mutualValue: window.mutualValue 
     onMutualValueChanged: setValue(mutualValue) 
     function setValue(mutualValue) 
     { 
      value = mutualValue 
     } 
    } 

    Text { 
     x: (parent.width - width)/2 
     y: 40 + (40 - height)/2 
     text: "Current value is: " + (window.mutualValue * 100).toFixed(2) + "%" 
    } 
} 
Смежные вопросы