Using urwid, how to display one line at a time wit

2019-07-11 17:39发布

Trying to create a simple function that displays one line from a text file at a time when enter or page down key is pressed. I don't want the lines to clear each time. In other words, I need to pause the program until next key press. As it is it only displays the first line. I tried a while True: to no avail. Thanks for you help!

# Handle key presses
def handle_input(key):
    with open('mobydick_ch1.txt') as f:
        lines = f.readlines()
        line_counter = 0
        if key == 'enter' or key == 'page down':
            text_box.base_widget.set_text(lines[line_counter])
            line_counter += 1
            main_loop.draw_screen()

        elif key == 'Q' or key == 'q':
            raise urwid.ExitMainLoop()

1条回答
Fickle 薄情
2楼-- · 2019-07-11 18:20

That's cool, it looks like you're building a program to read a big text one line at the time? =)

I believe the best way of doing this is to create a custom widget.

Maybe something like:

class LineReader(urwid.WidgetWrap):
    """Widget wraps a text widget only showing one line at the time"""
    def __init__(self, text_lines, current_line=0):
        self.current_line = current_line
        self.text_lines = text_lines
        self.text = urwid.Text('')
        super(LineReader, self).__init__(self.text)

    def load_line(self):
        """Update content with current line"""
        self.text.set_text(self.text_lines[self.current_line])

    def next_line(self):
        """Show next line"""
        # TODO: handle limits
        self.current_line += 1
        self.load_line()

And then you can use it like:

reader = LineReader(list(open('/etc/passwd')))

filler = urwid.Filler(reader)

def handle_input(key):
    if key in ('j', 'enter'):
        reader.next_line()
    if key in ('q', 'Q', 'esc'):
        raise urwid.ExitMainLoop

urwid.MainLoop(filler, unhandled_input=handle_input).run()

I've started using urwid a few months ago and am becoming a bit of a fan of the technique of custom widgets wrapping simple text widgets. =)

查看更多
登录 后发表回答