我是python的新手 - 抱歉,如果我的术语错了。我有一个继承Enthought Traits attributes的类。这是一个简化版本:
from enthought.traits.api import HasTraits, Range
from enthought.traits.ui.api import View, Item
class GUIThing(HasTraits):
my_slider = Range(0.0, 0.6, 0.1)
my_slider._high = 0.7 # works; not what I need 'coz not instance-dependent
view = View( Item('my_slider') )
def __init__(self, arg1):
# Call the parent's __init__
HasTraits.__init__(self)
self.my_slider._high = arg1 # what I need; doesn't work
# -- Main program -----
top_range = 0.9
my_gui = GUIThing(top_range)
my_gui.configure_traits()
这只会创建一个窗口,其中包含slider,最初从0.0到0.6,初始值为0.1。创建GUIThing实例时,我想根据当前top_range
值更改滑块的最大值。但行
self.my_slider._high = arg1
结果
AttributeError: 'float' object has no attribute '_high'
当在__init__()
范围内时,self.my_slider
不返回滑块对象,而是返回滑块的当前值。
我做错了什么?谢谢!
修改
以下也不起作用:
class GUIThing(HasTraits):
def __init__(self, arg1):
# Call the parent's __init__
HasTraits.__init__(self)
self.my_slider = Range(0.0, arg1, 0.0)
view = View( Item('my_slider') )
这将是我正在尝试做的直接方式,但它会导致GUI而不是滑块,有一个文本框,上面写着“enthought.traits.trait_types.Range对象在0xa61946c” 。所以问题是在my_slider
内创建__init__()
时,“my_slider”意味着对象本身(通过View无法正确显示);但如果在my_slider
之外创建__init__()
,则“my_slider”将表示当前值(浮点数;这会阻止访问对象属性)。
不确定这是Traits特有的还是我不知道如何正确初始化对象。
答案 0 :(得分:4)
最后在a recent mailing list message找到答案。
以下代码有效。似乎魔鬼在如何调用Range()的细节中:Range(my_slider_low, my_slider_hi, 0.1)
不工作。
from enthought.traits.api import HasTraits, Range
from enthought.traits.ui.api import View, Item
class GUIThing(HasTraits):
my_slider_low = 0.0
my_slider_hi = 1.0
my_slider = Range(low='my_slider_low', high='my_slider_hi', value=0.1)
def __init__(self, arg1):
self.my_slider_hi = arg1
view = View( Item('my_slider') )
top_range = 0.2
my_gui = GUIThing(top_range)
my_gui.configure_traits()
答案 1 :(得分:0)
我的内心感觉是你不需要修改那个类,而是扩展Range类并添加处理特定情况所需的额外逻辑。
答案 2 :(得分:0)
您需要使用add_trait方法,该方法可以使用您需要的值动态创建新的Range特征。
这取自Advanced page of the traits user manual
from traits.api import HasTraits, Range
class GUISlider (HasTraits):
def __init__(self, eval=None, label='Value',
trait=None, min=0.0, max=1.0,
initial=None, **traits):
HasTraits.__init__(self, **traits)
if trait is None:
if min > max:
min, max = max, min
if initial is None:
initial = min
elif not (min <= initial <= max):
initial = [min, max][
abs(initial - min) >
abs(initial - max)]
trait = Range(min, max, value = initial)
self.add_trait(label, trait)
答案 3 :(得分:0)
Pteridium的答案确实存在问题。它确实有效,但违反了两条规则/建议。
首先,您已使用自己的 init 覆盖了构造函数。如果你这样做(如果你可以避免,你不应该根据Traits的编码建议),你应该用类似的东西调用父构造函数 super(GUISlider,self)。 init (self,** kwargs)
其次,HasTraits子元素的推荐初始化是在构造函数的实例化过程中完成的,该构造函数采用关键字参数。在您的情况下,代码可能像
from enthought.traits.api import HasTraits, Range
from enthought.traits.ui.api import View, Item
class GUIThing(HasTraits):
my_slider_low = 0.0
my_slider_hi = 1.0
my_slider = Range(low='my_slider_low', high='my_slider_hi', value=0.1)
view = View( Item('my_slider') )
my_gui = GUIThing(my_slider_hi=0.4)
my_gui.configure_traits()
你去,做你想要的(我想),更少的代码,并遵循特征。如果有人能解释为什么我们不应该使用构造函数,我想知道。罗伯特克恩可能会告诉我们。
答案 4 :(得分:0)
我发现了dynamic range from Jonathan March.的一个很好的例子。这给出了OP想要AFAICT的所有行为:
# Imports:
from traits.api import HasPrivateTraits, Float, Range, Int
from traitsui.api import View, Group, Item, Label, RangeEditor
class DynamicRangeEditor ( HasPrivateTraits ):
""" Defines an editor for dynamic ranges (i.e. ranges whose bounds can be
changed at run time).
"""
# The value with the dynamic range:
value = Float
# This determines the low end of the range:
low = Float(0.0)
# This determines the high end of the range:
high = Float(50)
# Traits view definitions:
traits_view = View(
# Dynamic simple slider demo:
Group(
Item( 'value',
editor = RangeEditor( low_name = 'low',
high_name = 'high',
format = '%.1f',
label_width = 28,
mode = 'auto' )
),
'_',
Item( 'low' ),
Item( 'high' ),
'_',
),
title = 'Dynamic Range Editor Demonstration',
buttons = [ 'OK' ],
resizable = True
)
# Create the demo:
demo = DynamicRangeEditor()
# Run the demo (if invoked from the command line):
if __name__ == '__main__':
demo.configure_traits()