TabularAdapter编辑器问题

时间:2015-01-06 23:55:15

标签: editor enthought traitsui

我在TraitsUI包中遇到了TabularAdapter的问题......

我现在已经试图自己解决这个问题太久了,所以我想请各位专家提供一些友好的建议:)

我要添加一段我的程序来说明我的问题,我希望有人可以查看并说“啊哈!...在这里&# 39;你的问题' (我的手指交叉)。

基本上,我可以使用TabularAdapter将表编辑器生成为dtypes数组,除了以下情况之外它的工作正常:

1)每当我更改元素数量(标识为'骨折数量:')时,数组会调整大小,但表格在我点击之后才会反映出更改其中一个要素。我想要发生的是,在释放#of fractures滑块后,行数(骨折)发生了变化。这可行吗?

2)我遇到的第二个问题是,如果数组在由.configure_traits()显示之前调整大小(由Number_of_fractures修改后的通知程序),我可以缩小数组的大小,但是我不能在新尺寸上增加它。

2b)我以为我找到了一种让表格编辑器显示完整数组的方法,即使它超过了代码中的5个集合(在调用.trait_configure()之前),但是我被愚弄了:(我尝试在vertical_fracture_group前添加另一个Group(),所以表格不是第一个显示的东西。这更接近于模拟我的整个程序。当我这样做时,我被锁定在新的数组的较小尺寸,我不能再将其大小增加到最大值15.我修改代码以反映此问题。

这是我的示例代码:

# -*- coding: utf-8 -*-
"""
This is a first shot at developing a ****** User Interface using Canopy by
Enthought.  Canopy is a distribution of the Python language which has a lot of
scientific and engineering features 'built-in'.
"""


#-- Imports --------------------------------------------------------------------

from traitsui.api import TabularEditor
from traitsui.tabular_adapter import TabularAdapter
from numpy import zeros, dtype

from traits.api import HasTraits,  Range

from traitsui.api import View, Group, Item

#-- FileDialogDemo Class -------------------------------------------------------

max_cracks = 15     #maximum number of Fracs/cracks to allow

class VertFractureAdapter(TabularAdapter):
    columns = [('Frac #',0), ('X Cen',1), ('Y Cen',2), ('Z Cen',3),
        ('Horiz',4), ('Vert',5), ('Angle',6)]



class SetupDialog ( HasTraits ):
    Number_Of_Fractures = Range(1, max_cracks) # line 277

    vertical_frac_dtype = dtype([('Fracture', 'int'), ('x', 'float'), ('y', 'float'),
            ('z', 'float'), ('Horiz Length', 'float'), ('Vert Length', 'float')
            , ('z-axis Rotation, degrees', 'float')])
    vertical_frac_array = zeros((max_cracks), dtype=vertical_frac_dtype)

    vertical_fracture_group = Group(
        Item(name = 'vertical_frac_array',
            show_label = False,
            editor     = TabularEditor(adapter = VertFractureAdapter()),
            width = 0.5,
            height = 0.5,
        )
    )


    #-- THIS is the actual 'View' that gets put on the screen
    view = View(
        #Note: When as this group 'displays' before the one with the Table, I'm 'locked' into my new maximum table display size of 8 (not my original/desired maximum of 15)
        Group(
            Item( name = 'Number_Of_Fractures'),
        ),

        #Note: If I place this Group() first, my table is free to grow to it's maximum of 15
        Group(
            Item( name = 'Number_Of_Fractures'),
            vertical_fracture_group,
        ),

        width = 0.60,
        height = 0.50,
        title = '****** Setup',
        resizable=True,
    )


    #-- Traits Event Handlers --------------------------------------------------
    def _Number_Of_Fractures_changed(self):
        """ Handles resizing arrays if/when the number of Fractures is changed"""
        print "I've changed the # of Fractures to " + repr(self.Number_Of_Fractures)
        #if not self.user_StartingUp:
        self.vertical_frac_array.resize(self.Number_Of_Fractures, refcheck=False)

        for crk in range(self.Number_Of_Fractures):
            self.vertical_frac_array[crk]['Fracture'] = crk+1
            self.vertical_frac_array[crk]['x'] = crk
            self.vertical_frac_array[crk]['y'] = crk
            self.vertical_frac_array[crk]['z'] = crk



# Run the program (if invoked from the command line):
if __name__ == '__main__':
    # Create the dialog:
    fileDialog = SetupDialog()

    fileDialog.configure_traits()

    fileDialog.Number_Of_Fractures = 8

在我与Chris的讨论中,他提出了一些建议,到目前为止还没有对我有用:(以下是我目前的测试代码版本所以Chris(或其他任何人)我希望能够知道我是否犯了一些明显的错误。

# -*- coding: utf-8 -*-
"""
This is a first shot at developing a ****** User Interface using Canopy by
Enthought.  Canopy is a distribution of the Python language which has a lot of
scientific and engineering features 'built-in'.
"""


#-- Imports --------------------------------------------------------------------

from traitsui.api import TabularEditor
from traitsui.tabular_adapter import TabularAdapter
from numpy import zeros, dtype

from traits.api import HasTraits,  Range, Array, List

from traitsui.api import View, Group, Item

#-- FileDialogDemo Class -------------------------------------------------------

max_cracks = 15     #maximum number of Fracs/cracks to allow

class VertFractureAdapter(TabularAdapter):
    columns = [('Frac #',0), ('X Cen',1), ('Y Cen',2), ('Z Cen',3),
        ('Horiz',4), ('Vert',5), ('Angle',6)]
    even_bg_color = 0xf4f4f4 # very light gray



class SetupDialog ( HasTraits ):
    Number_Of_Fractures = Range(1, max_cracks) # line 277
    dummy = Range(1, max_cracks)

    vertical_frac_dtype = dtype([('Fracture', 'int'), ('x', 'float'), ('y', 'float'),
            ('z', 'float'), ('Horiz Length', 'float'), ('Vert Length', 'float')
            , ('z-axis Rotation, degrees', 'float')])
    vertical_frac_array = Array(dtype=vertical_frac_dtype)

    vertical_fracture_group = Group(
        Item(name = 'vertical_frac_array',
            show_label = False,
            editor     = TabularEditor(adapter = VertFractureAdapter()),
            width = 0.5,
            height = 0.5,
        )
    )


    #-- THIS is the actual 'View' that gets put on the screen
    view = View(
        Group(
            Item( name = 'dummy'),
        ),

        Group(
            Item( name = 'Number_Of_Fractures'),
            vertical_fracture_group,
        ),

        width = 0.60,
        height = 0.50,
        title = '****** Setup',
        resizable=True,
    )


    #-- Traits Event Handlers --------------------------------------------------
    def _Number_Of_Fractures_changed(self, old, new):
        """ Handles resizing arrays if/when the number of Fractures is changed"""
        print "I've changed the # of Fractures to " + repr(self.Number_Of_Fractures)
        vfa = self.vertical_frac_array
        vfa.resize(self.Number_Of_Fractures, refcheck=False)

        for crk in range(self.Number_Of_Fractures):
            vfa[crk]['Fracture'] = crk+1
            vfa[crk]['x'] = crk
            vfa[crk]['y'] = crk
            vfa[crk]['z'] = crk

        self.vertical_frac_array = vfa



# Run the program (if invoked from the command line):
if __name__ == '__main__':
    # Create the dialog:
    fileDialog = SetupDialog()

    # put the actual dialog up...if I put it up 'first' and then resize the array, I seem to get my full range back :)
    fileDialog.configure_traits()

    #fileDialog.Number_Of_Fractures = 8

1 个答案:

答案 0 :(得分:5)

导致您描述的问题的代码有两个细节。首先,vertical_frac_array不是特征,因此表格编辑器无法监视它的变化。因此,表只有在您手动与其交互时才会刷新。其次,traits不会监视数组的内容以进行更改,而是监视数组的标识。因此,将无法检测到调整大小并将值分配到数组中。

解决此问题的一种方法是首先制作vertical_frac_arrayArray特质。例如。 vertical_frac_array = Array(dtype=vertical_frac_dtype)。然后,在_Number_Of_Fractures_changed内,不要resize vertical_frac_array并在原地进行修改。而是复制vertical_frac_array,调整其大小,修改内容,然后将操纵的副本重新分配回vertical_frac_array。这样,表格将看到数组的标识已更改并将刷新视图。

另一种选择是vertical_frac_array成为List而不是Array。这避免了上面的复制和重新分配技巧,因为特征确实监视列表的内容。

修改

我的解决方案如下。而不是在vertical_frac_array更改时调整Number_Of_Fractures,而是重新创建数组。我还通过vertical_frac_array方法为_vertical_frac_array_default提供了默认值。 (我也从视图中不必要的代码中删除了。)

# -*- coding: utf-8 -*-
"""
This is a first shot at developing a ****** User Interface using Canopy by
Enthought.  Canopy is a distribution of the Python language which has a lot of
scientific and engineering features 'built-in'.
"""


#-- Imports --------------------------------------------------------------------

from traitsui.api import TabularEditor
from traitsui.tabular_adapter import TabularAdapter
from numpy import dtype, zeros

from traits.api import HasTraits,  Range, Array

from traitsui.api import View, Item

#-- FileDialogDemo Class -------------------------------------------------------

max_cracks = 15     #maximum number of Fracs/cracks to allow

vertical_frac_dtype = dtype([('Fracture', 'int'), ('x', 'float'), ('y', 'float'),
        ('z', 'float'), ('Horiz Length', 'float'), ('Vert Length', 'float')
        , ('z-axis Rotation, degrees', 'float')])


class VertFractureAdapter(TabularAdapter):
    columns = [('Frac #',0), ('X Cen',1), ('Y Cen',2), ('Z Cen',3),
        ('Horiz',4), ('Vert',5), ('Angle',6)]


class SetupDialog ( HasTraits ):

    Number_Of_Fractures = Range(1, max_cracks) # line 277
    vertical_frac_array = Array(dtype=vertical_frac_dtype)

    view = View(
        Item('Number_Of_Fractures'),
        Item(
            'vertical_frac_array',
            show_label=False,
            editor=TabularEditor(
                adapter=VertFractureAdapter(),
            ),
            width=0.5,
            height=0.5,
        ),
        width=0.60,
        height=0.50,
        title='****** Setup',
        resizable=True,
    )

    #-- Traits Defaults -------------------------------------------------------

    def _vertical_frac_array_default(self):
        """ Creates the default value of the `vertical_frac_array`. """
        return self._calculate_frac_array()

    #-- Traits Event Handlers -------------------------------------------------

    def _Number_Of_Fractures_changed(self):
        """ Update `vertical_frac_array` when `Number_Of_Fractures` changes """
        print "I've changed the # of Fractures to " + repr(self.Number_Of_Fractures)
        #if not self.user_StartingUp:
        self.vertical_frac_array = self._calculate_frac_array()

    #-- Private Interface -----------------------------------------------------

    def _calculate_frac_array(self):
        arr = zeros(self.Number_Of_Fractures, dtype=vertical_frac_dtype)
        for crk in range(self.Number_Of_Fractures):
            arr[crk]['Fracture'] = crk+1
            arr[crk]['x'] = crk
            arr[crk]['y'] = crk
            arr[crk]['z'] = crk
        return arr


# Run the program (if invoked from the command line):
if __name__ == '__main__':
    # Create the dialog:
    fileDialog = SetupDialog()

    fileDialog.configure_traits()