[Urwid] Strange behaviour of ListBox

jm at jm10.no-ip.com jm at jm10.no-ip.com
Sat Jul 15 14:05:11 EDT 2006


Hello,

I am a member of the Hachoir[1] project[2] and we have chosen urwid for the text
interface :)
Here is a screenshot:
http://www.haypocalc.com/hachoir/screenshot/hachoir_urwid_040.png
and the source code for the urwid ui:
http://hachoir.python-hosting.com/file/hachoir/trunk/src/hachoir/ui/urwid/urwid_ui.py

I use a ListBox to display the tree and it has a strange behaviour, contrary to
the browse.py example of urwid:
(0. Do anything so that there is enough content.)
1. Press the 'down' key and repeat until it starts scrolling.
   (Or move the cursor to the end.)
2. Move the cursor one[3] line up.
3. The listbox scrolls and the cursors sticks to the footer. Instead, only the
cursor should move and the previously selected item should stay visible.
The attached program is a simplified testcase.

I tried to play with ListBox.shift_focus (or ListBox.offset_rows) but it seems
to do nothing.

I really wonder what I missed in browse.py.

JM

[1] 'hachoir' is a french word: http://www.wordreference.com/fren/hachoir
[2] http://hachoir.python-hosting.com/
[3] The number depends of the height of the footer. If the footer has a height 3
lines, the listbox bugs 3 times.
-------------- next part --------------
#! /usr/bin/python2.4
from urwid import Text, AttrWrap, ListBox, Frame
import urwid.curses_display

class Item(AttrWrap):
    def __init__(self, text):
        AttrWrap.__init__(self, Text(text, wrap='clip'), None, 'focus')

    def selectable(self):
        return True

    def keypress(self, (maxcol,), key):
        return key

class Walker:
    def __init__(self):
        self.items = [ Item(str(i)) for i in xrange(256) ]
        self.focus = 0

    def _get(self, pos):
        if 0 <= pos < len(self.items):
            return self.items[pos], pos
        return None, None

    def get_focus(self):
        return self._get(self.focus)

    def get_next(self, pos):
        return self._get(pos + 1)

    def get_prev(self, pos):
        return self._get(pos - 1)

    def set_focus(self, pos):
        self.focus = pos


def main():
    ui = urwid.curses_display.Screen()
    ui.register_palette((
        ('focus', 'white', 'dark blue'),
        ('footer', 'white', 'dark red'),
    ))

    body = ListBox(Walker())
    top = Frame(body, footer=AttrWrap(Text(''), 'footer'))

    def run():
        events = ( "window resize", )
        while True:
            for e in events:
                if e == "window resize":
                    size = ui.get_cols_rows()
                    #body.shift_focus(size, 10)
                elif e == 'q':
                    return
                else:
                    body.keypress(size, e)
            ui.draw_screen(size, top.render(size, focus=True))
            while True:
                events = ui.get_input()
                if events: break

    ui.run_wrapper(run)

if __name__=="__main__":
    main()


More information about the Urwid mailing list