2

I've found that I can apply a format to ALL the columns in a TabularAdapter by adding a statement like this to the TabularAdapter declaration: format = '%7.4f'.

However, I'd like to have different formatting for each column in the table...is this possible? I've tried to specify the format for just column index 2 (as seen in the example below), but it doesn't apply to just that column. I've been searching for how to do this correctly, but so far have found nothing.

Here's a little example file:

from traits.api import HasTraits, Array

from traitsui.api import View, Group,Item, TabularEditor
from traitsui.tabular_adapter import TabularAdapter
from numpy import dtype

test_dtype = dtype([('Integer#1', 'int'), ('Integer#2', 'int'), ('Float', 'float')])

class testArrayAdapter(TabularAdapter):
    columns = [('Col1 #', 0), ('Col2', 1), ('Col3', 2)]
    even_bg_color = 0xf4f4f4 # very light gray
    width = 125

class test(HasTraits):
    test_array = Array(dtype=test_dtype)

    view = View(
        Item(name = 'test_array',
            show_label = False,
            editor     = TabularEditor(adapter = testArrayAdapter()),
        ),
        Item(name = 'test_array',
            show_label = False,
            editor     = TabularEditor(adapter = testArrayAdapter(column=2, format='%.4f')),
        ),
    )


Test = test()
Test.test_array.resize(5, refcheck = False)
Test.configure_traits()

What I'd like to see is to have the 3rd column have the 4 decmals (it is a float after all), while columns 1 & 2 are presented as just integers.

Warren Weckesser
  • 110,654
  • 19
  • 194
  • 214
Steve76063
  • 317
  • 2
  • 10

1 Answers1

2

There are at least two ways you can do this. One is to override the method get_format(self, object, name, row, column) of the TabularAdapter in your adapter class, and have it return the appropriate format based on the column argument. E.g.

    def get_format(self, object, name, row, column):
        formats = ['%d', '%d', '%.4f']
        return formats[column]

Another method is to use the "traits magic" that is implemented in the TabularAdapter class. In your subclass, you can set the format for a column by defining a specially named Str trait. One set of names that works for a numpy structured array such as your test_array is

    object_0_format = Str("%d")
    object_1_format = Str("%d")
    object_2_format = Str("%.4f")

(See the TabularAdapter documentation, and this file in the github repo for more information.)

Here's a modified version of your script that demonstrates both approaches. For variety, I used the format "%04d" for the first column. (I hope you don't mind the gratuitous name and style changes.)

from traits.api import HasTraits, Array, Str
from traitsui.api import View, Item, TabularEditor
from traitsui.tabular_adapter import TabularAdapter
from numpy import dtype


test_dtype = dtype([('Integer#1', 'int'),
                    ('Integer#2', 'int'),
                    ('Float', 'float')])


class TestArrayAdapter1(TabularAdapter):

    columns = [('Col1 #', 0), ('Col2', 1), ('Col3', 2)]

    even_bg_color = 0xf4f4f4  # very light gray

    width = 125

    def get_format(self, object, name, row, column):
        formats = ['%04d', '%d', '%.4f']
        return formats[column]


class TestArrayAdapter2(TabularAdapter):

    columns = [('Col1 #', 0), ('Col2', 1), ('Col3', 2)]

    even_bg_color = 0xf4f4f4  # very light gray

    width = 125

    object_0_format = Str("%04d")
    object_1_format = Str("%d")
    object_2_format = Str("%.4f")


class Test(HasTraits):

    test_array = Array(dtype=test_dtype)

    view = \
        View(
            Item(name='test_array', show_label=False,
                 editor=TabularEditor(adapter=TestArrayAdapter1())),
            Item(name='test_array', show_label=False,
                 editor=TabularEditor(adapter=TestArrayAdapter2())),
        )


test = Test()
test.test_array.resize(5, refcheck=False)
test.configure_traits()
Warren Weckesser
  • 110,654
  • 19
  • 194
  • 214
  • AWESOME Warren! You saved me so much searching and trial and error! I just hope that someday I'm proficient enough in Canopy to help someone else. – Steve76063 Mar 28 '15 at 21:56
  • Warren...it appears that you have some in-depth knowledge of Tabular Adapters...Do you know if it's possible to DEF a notification for a change to an individual element (like for a number changing in any row/column)? I've searched for notifications on individual Array elements, but have had no luck. Seeing what can be done with the def get_format() override, I was wondering if there's something similar for a value changing??? (my fingers are crossed :) ) – Steve76063 Mar 28 '15 at 22:08
  • For a numpy array, there are probably some hacks you could use (e.g. override the `set_text` method of the `TabularAdapter`). You should ask this in a new question, so more of the active `TraitsUI` users can see it (there are a few here on SO). – Warren Weckesser Mar 29 '15 at 15:17