2012-03-31 104 views
5

我是python新手 - 抱歉,如果我的術語錯誤。我有一個繼承Enthought Traits attributes的類。下面是一個簡化的版本:在類構造函數中更改屬性參數[Python/Traits]

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哪裏而不是一個滑塊,有一個文本框中讀取「0xa61946c」enthought.traits.trait_types.Range對象。所以問題是,當在__init__()內創建my_slider時,那麼「my_slider」是指對象本身(它不能通過View正確顯示)。但如果在__init__()之外創建my_slider,則「my_slider」意味着當前值(防止訪問對象屬性的浮點數)。

不確定這是否是特徵特有的,或者我只是不知道如何正確初始化對象。

+3

一般來說,在''_high''的前綴下劃線意味着它是私有的,你不應該像那樣訪問它。 – 2012-03-31 13:38:38

+0

對,謝謝。但是我無法在文檔中找到如何訪問它。即使它不是正確的方式 - 它在'__init__'之外工作。所以我不明白爲什麼它在*'__init__'內不同*(另見編輯到OP)。 – Pteridium 2012-03-31 15:35:13

+0

我的猜測(我不熟悉庫)是超類的__init __()''使用''Range'',但不參考它。如果這是真的,你有沒有嘗試在'__init __()'''內的'HasTraits .__ init __(self)'之前放置'self.my_slider = Range(0.0,arg1,0.0)''? – 2012-03-31 16:11:34

回答

0

我的直覺是,你並不需要修改類的,而是擴大範圍類,並添加您需要處理您的特定情況下,額外的邏輯。

+0

謝謝,一個問題是我無法找到Range如何在內部工作;它實際上並不是一個類,而是一個函數/'類型定義'...見[這裏](http://code.enthought.com/projects/files/ets_api/enthought.traits.traits.html )?我很困惑。 – Pteridium 2012-03-31 15:41:47

+0

不需要亂用Range - 它具有OP – DrSAR 2012-05-03 05:31:45

0

您需要使用add_trait方法,該方法將使您能夠使用所需的值動態創建新的範圍特徵。

這是從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) 
+0

所需的所有功能謝謝!我沒有注意到這一點。是的,如果向類添加'view = View(Item('Value'))',它就可以工作。如果你想用不同的標籤製作多個GUISliders,那就不行了。 – Pteridium 2012-03-31 22:05:21

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() 
0

蕨類植物的答案實際上存在問題。它確實有效,但打破了兩條規則/建議。

首先,已覆蓋構造用自己的的init。如果你這樣做(如果可以避免的話,你不應該根據Traits的編碼建議),你應該調用父類構造函數,例如 super(GUISlider,self)。其次,建議使用關鍵字參數的構造函數在實例化過程中完成對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() 

你走了嗎,你想要什麼(我認爲),更少的代碼,並遵循特質。如果有人能解釋爲什麼我們不應該使用構造函數,我想知道。羅伯特克恩可以告訴我們。

+0

這對我不起作用,滑塊始終顯示初始值1.0 – kezzos 2014-06-09 14:58:01

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()