0

I'm trying to learn how to use Traits for building simple UIs for my Python scripts. I want to make a programme with a list which the user can add words to with one button, or to clear the list completely with another.

So far, I've used traits:

myList = List(Str)

myList = ['Item1','Item2'] #Initial items in list

To display this list in a traits UI, I used ListStrEditor from the traits UI package:

Item('myList', show_label = False, label = 'Data Files', editor = ListStrEditor(auto_add = False)

I have coded 2 buttons: 1) one for ADDing an item to the list (myList.append('item3')) 2) a CLEAR button to empty the list (myList = []). The basic UI is good, the buttons work and my list variable is changed as expected.

However, the problem is, that my list in the GUI doesn't update. If I click on it the new values are displayed, however. Also, I want to potentially add many items to it and wonder if there is a way to add a scrollbar to the side?

I've looked up the ListStrEditor manual and usage, although I'm getting a bit bogged down with terminology. Apparently a refresh() function exists, but I'm not sure how to apply it to ListStrEditor. Also, I'm not sure if I need to use things called "adapters" or "handlers".

Any tips or pointers in the right direction would be much appreciated!

Ulf Gjerdingen
  • 1,414
  • 3
  • 16
  • 20
RobMSN
  • 87
  • 1
  • 6

1 Answers1

4

Without seeing more complete code, it is difficult to know why your code is not working. Perhaps you are missing the use of self? E.g. self.myList.append('Item3') instead of just myList.append('Item3')?

The following works for me. The display of the list updates as soon as the buttons are pressed.

import random

from traits.api import HasTraits, List, Str, Button
from traitsui.api import ListStrEditor, View, UItem


class Demo(HasTraits):

    my_list = List(Str)

    add = Button("ADD")
    clear = Button("CLEAR")

    traits_view = \
        View(
            UItem('my_list', editor=ListStrEditor(auto_add=False)),
            UItem('add'),
            UItem('clear'),
        )

    def _my_list_default(self):
        return ['Item1', 'Item2']

    def _add_fired(self):
        new_item = "Item%d" % random.randint(3, 999)
        self.my_list.append(new_item)

    def _clear_fired(self):
        self.my_list = []


if __name__ == "__main__":
    demo = Demo()
    demo.configure_traits()

It works with both the wx and qt4+pyside backends. I'm using the Enthought python distribution, EPD 7.3, which has version 4.2.0 of Traits and TraitsUI.

If your code is significantly different, could you add it to the question?

Warren Weckesser
  • 110,654
  • 19
  • 194
  • 214
  • Thanks, this works excellently. This is very similar to my code (nb, I didn't reply in time to give a minimum working example sorry!) although I'd put `my_list = ['item1', 'item2']` straight after `my_list = List(str)` which I assume is what caused the issue. Thanks for your help! PS, I note you've used UItem rather than Item. Both seem to work, is there any benefit to using UItem? – RobMSN Feb 11 '13 at 02:24
  • 1
    `UItem` is a subclass of `Item` with `show_label = False`--that's it. Take a look at the source here: https://github.com/enthought/traitsui/blob/master/traitsui/item.py – Warren Weckesser Feb 11 '13 at 03:43
  • Also, I used the method `_my_list_default` to set the default value, but that's probably overkill in this case. Instead, the default can be given in the trait declaration, using the `value` keyword`: `my_list = List(Str, value=['Item1', 'Item2'])` – Warren Weckesser Feb 11 '13 at 12:25
  • Thanks, that's useful to know! – RobMSN Feb 11 '13 at 16:32
  • Do you know if there's a way to make the scrollbar sit at the bottom, so that new entries cause the display to 'scroll up', rather than resetting the view to the first N entries? – davidA Nov 24 '13 at 02:53