2016-01-23 2 views
-1

Существует автономный пример задачи:Slider элемент поддерживает сброс целевого значения до минимального значения слайдера

Rectangle { 
    id: rect 
    width: 200 
    height: 200 
    property real v : 50 
    onVChanged: console.log(v) 
    Button { 
     onClicked: scomp.createObject(rect) 
    } 
    Component { 
     id: scomp 
     Rectangle { 
      id: sli 
      anchors.fill: parent 
      Column { 
       Slider { 
        width: 200 
        minimumValue: 10 
        maximumValue: 100 
        value: rect.v 
        onValueChanged: rect.v = value 
       } 
       Button { 
        onClicked: sli.destroy() 
       } 
      } 
     } 
    } 
} 

В принципе, каждый раз, когда компонент слайдера создан, чтобы изменить v он устанавливает его минимальное значение ползунка , Обратите внимание, что слайдер по-прежнему будет работать правильно, чтобы изменить это значение, а v сохранит свое правильное значение после того, как слайдер будет закрыт, но в тот момент, когда он снова откроется, значение снова развращается.

Почему это происходит, как его предотвратить? Казалось бы, по какой-то объяснимой причине свойство slider value временно принимает значение minimumValue, но это не похоже на адекватное поведение. Может быть, ошибка? Ползунок никогда не принимает правильное начальное значение, даже если value: rect.v перемещается перед установкой минимального значения.

ответ

-1

Не копаясь в реализации элемента Slider, кажется, что порядок реализации был плохо спроектирован, начальное значение равно 0.0, поэтому установка минимального значения на что-либо более высокое также увеличивает значение. И не имеет значения, связано ли значение с чем-то более высоким, чем минимальное значение, из-за порядка оценки значение всегда равно 0.0, когда задано минимальное значение, поэтому в этом формате целевое значение всегда будет искажено на слайдер минимальное значение.

Решение, которое я придумал, позволяет избежать этого поведения, задерживая привязку целевого значения, оно работает, но оно не так красиво, поэтому я по-прежнему открыт для других решений, между тем Qt guys - если вы видите это, хочу исправить Slider:

Slider { 
    width: 200 
    minimumValue: 10 
    maximumValue: 100 
    value: rect.v 
    Component.onCompleted: valueChanged.connect(function(){ rect.v = value}) 
} 

Этот формат еще изначально выталкивает значение ползунка до минимального значения, но в это время связывания установить целевое значение пока не существует, он будет создан только после того, как значение ползунка принимает правильное значение.

+0

Вы не должны полагаться на 'valueChanged' вообще, поскольку, как и все другие обработчики, вызывается при каждом изменении значения, даже начальные присваивания. Плохой выбор дизайна? Вы можете спорить об этом, но так оно и работает. Вместо этого привяжите значение к значению ползунка: значение обновляется с помощью ползунка. Что-то вроде [этого] (http://pastebin.com/raw/62cXrMqz). – BaCaRoZzo

+0

@BaCaRoZzo Ваш код абсурден, очевидно, что ползунок разрушен после того, как была выполнена настройка, привязка целевого значения к значению слайдера - самое худшее «решение» проблемы и фактически даже не решение. Если ползунок был правильно реализован, установка значения ползунка в целевое значение не будет возвращаться к целевому значению, так как значение будет одинаковым. В слайдере есть изменение паразитного значения, и да, паразитное непреднамеренное поведение - плохой дизайн. И это плохой дизайн, который предотвращает использование компонента самым чистым и самым логичным способом. – IvanB

+0

Не будучи функциональным в стороне, ваше решение на самом деле предлагает привязать данные к пользовательскому интерфейсу, что само по себе является очень плохим дизайном. Пользовательский интерфейс связывается с данными, данные не должны зависеть от пользовательского интерфейса. Пользовательский интерфейс подходит для визуализации или взаимодействия с данными. – IvanB

1

Это не ошибка в Slider, это ваше использование этого:

onValueChanged: rect.v = value 

Если добавить еще некоторые отладочные:

qml: maximumValue = 100 value = 0 
qml: minimumValue = 10 value = 10 
qml: value = 10 
qml: v = 10 
void __cdecl QQuickRangeModel::setValue(double) 10 
qml: in Component.onCompleted of Slider: value = 10 minimumValue = 10 maximumValue = 100 

Перед этим даже получает шанс завершить загрузку, вы 'уже назначил свой value на v. Правильное решение зависит от ваших требований, о которых вы не упомянули. Например, одно решение было бы указать значение по умолчанию в Slider вместо этого, и привязать v к value:

v: slider ? slider.value : 0 

, кажется, что порядок реализации был плохо разработан

How would you design it?

+0

Это не полезный формат использования. Он может работать в крошечном изолированном примере, но это невозможно сделать на производстве. Значение модификации minimumValue звучит как плохое дизайнерское решение. Это означает, что пользователь использовал ползунок, чтобы указать значение, но происходит без какого-либо взаимодействия с пользователем. – IvanB

+1

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

+0

Да, привязка данных к элементам пользовательского интерфейса, безусловно, не самая лучшая идея. И QtQuick Controls далеки от совершенства, они всего лишь слабая тень QtWidgets, все еще незрелая и отстающая по характеристикам. Элементы управления полезны только для рудиментарных приложений, я попытался использовать их в производстве и в итоге реализовал свои компоненты практически для каждого элемента, который я пытался использовать. Проблемы с дизайном на разных платформах, проблемы с поведением, IMO - это полузапеченная приманка, чтобы заманить пользователей QtWidgets в QML. Не стоит головной боли, просто сделайте свой собственный слайдер. – dtech

Смежные вопросы