2016-10-12 4 views
1

Похоже, RangeEditor является проводником, чтобы ожидать поплавок. Следующий пример сценария иллюстрирует поведение. Есть ли более чистый способ указать RangeEditor для целочисленного признака?Неожиданный RangeEditor для целых чисел

import sys 
print (sys.version) # '3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:18:55) [MSC v.1900 64 bit (AMD64)]' 
from traits import __version__ 
print (__version__) # '4.6.0.dev0' 

from traits.api import HasTraits, Int, Range 
from traitsui.api import Item, RangeEditor, View 

class Exposure (HasTraits): 

    duration = Range (low=0.0, high=3600.0, exclude_low=True , exclude_high=False, editor=RangeEditor(mode='slider')) 
    min_count = Int ( 1) 
    max_count = Int (10000) 
    #<1>count = Range (low=1 , high=10000 , exclude_low=False, exclude_high=False, editor=RangeEditor(mode='slider')) 
    count  = Range (low=1 , high=10000 , exclude_low=False, exclude_high=False, editor=RangeEditor(mode='slider', low_name='min_count', high_name='max_count')) 
    traits_view = View (Item('duration'), Item('count'), buttons=['OK', 'Cancel']) 
exposure = Exposure (duration = 0.00032, count=1500) 
exposure.configure_traits() 

# Specifying `count` as per <1>, above, raises the following exception: 
# traits.trait_errors.TraitError: The 'count' trait of an Exposure instance must be 1 <= a long integer <= 10000, but a value of 1.0 <class 'float'> was specified. 
# 
# A work-around is to declare min_count and max_count, and include them in the 
# RangeEditor definition of `count`. Note, I am now duplicating `count` low and 
# high limits in 2 places. Is there a better approach? 

ответ

2

RangeEditor действительно по умолчанию возвращаются float значения, если не изменить настройки по умолчанию, установив high или low параметров int значений. Параметры low и high признака Range не передаются в редактор по умолчанию этого признака (see the source here), поэтому вы должны установить их отдельно. (Из источника должно быть очевидно, почему использование low_name и high_nameвыполнено работа.) IIUC, это преднамеренное разделение признака с его точки зрения, но вы можете открыть проблему в «Чертах» для обсуждения, если вы думаете, что поведение должно быть разным.

Одна вещь, которая может помочь прояснить ваш код, заключается в разделении определений вашей модели и вида. Указание редакторов в ваших определениях признаков облегчает смешивание w.r.t. параметры признака по сравнению с его представлением. Если ограничения на значение являются неотъемлемой частью модели Exposure, используйте Range, иначе просто используйте базовый тип признаков. Определение представления отдельно делает ваш код более четким: какие ограничения принадлежат модели, а какие - к виду. Кроме того, если вы хотите определить второе представление с различными ограничениями, это не проблема.

Вот как я хотел бы предложить повторно писать код:

from traits.api import HasTraits, Int, Range 
from traitsui.api import Item, RangeEditor, View 

class Exposure (HasTraits): 

    duration = Range (low=0.0, high=3600.0, exclude_low=True , exclude_high=False) 
    count  = Int(1500) 

my_view = View(
    Item('duration', editor=RangeEditor(mode='slider')), 
    Item('count', editor=RangeEditor(low=1, high=10000, mode='slider')), 
    buttons=['OK', 'Cancel'] 
) 
exposure = Exposure (duration = 0.00032, count=1500) 
exposure.configure_traits(view=my_view) 
+0

Спасибо за подробный ответ. Я действительно хочу, чтобы 'count' был диапазоном для принудительного применения ограничений. Кроме того, спецификация Item для 'duration' должна включать значения low & high; в противном случае RangeEditor представляет слайдер для [0.0, 1.0]. Я понимаю MVC, но учитывая, что Range low & high должен быть указан как в декларации признака (модели), так и в объявлении RangeEditor (view) RangeEditor (нарушение DRY IMHO), я предпочитаю держать их вместе в определении класса (модели) , –

+0

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

+0

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

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