[Urwid] How to capture & display output from second application in the background?

Dominic LoBue dom.lobue at gmail.com
Thu Jun 4 17:38:33 EDT 2009


Hello,

I am trying to figure out how to fork a command in the background and
capture that program's stdout into a listbox, but I'm new to urwid and
programming with threads.

To be specific, my aim is to write a mail client with a urwid front
end that uses offlineimap running in the background to keep my local
mail store in sync with the server. I want to have the output from
offlineimap stored in a hidden listbox for both "wow" factor, and as a
debugging tool.

Here's a small example to show you what I mean:
Tiny program that outputs text like how offlineimap outputs text:
# doubler.py
#!/usr/bin/env python

import time
def godouble():
    a = 1
    c = 0
    while 1:
        a *= 2
        c += 1
        print a
        time.sleep(1)
        if c > 100: break

if __name__ == '__main__':
    godouble()




And here's a modified version of the irc client that has two listboxes
you can switch between using f1 and f2. The f2 listbox should contain
the output from the doubler.py program above, but I haven't the
faintest idea where to start:

# simplifiedirc.py
#!/usr/bin/python

import urwid.curses_display
import urwid

class Screen:
    def __init__(self, tui):
        self.tui = tui

    def addLine(self, text):
        self.lines.append(urwid.Text(text))
        self.listbox.set_focus(len(self.lines) - 1)
        self.redisplay()

    def addLine2(self, text):
        self.lines2.append(urwid.Text(text))
        self.listbox2.set_focus(len(self.lines2) - 1)
        self.redisplay()

    def redisplay(self):
        canvas = self.frame.render(self.size, focus=True)
        self.tui.draw_screen(self.size, canvas)

    def run(self):
        self.size = self.tui.get_cols_rows()

        self.lines = [urwid.Text('Hello')]
        self.lines2 = [urwid.Text('Hello2')]
        self.listbox = urwid.ListBox(self.lines)
        self.listbox2 = urwid.ListBox(self.lines2)
        self.input = urwid.Edit()
        self.summarytxt = urwid.Text('inbox, blalkjsdfn 093 emails',
align='left')

        self.bframe = urwid.Pile([self.summarytxt, self.input])

        self.frame = urwid.Frame(self.listbox, footer=self.bframe)
        self.frame.set_focus('footer')

        self.redisplay()

        while 1:
            keys = self.tui.get_input()

            for key in keys:
                if key == 'window resize':
                    self.size = self.tui.get_cols_rows()
                elif key == 'enter':
                    text = self.input.get_edit_text()
                    self.input.set_edit_text('')
                    self.addLine(text)
                elif key in ('up', 'down', 'page up', 'page down'):
                    self.listbox.keypress(self.size, key)
                elif key == 'f1':
                    self.frame.set_body(self.listbox)
                elif key == 'f2':
                    self.frame.set_body(self.listbox2)
                else:
                    self.frame.keypress(self.size, key)

                self.redisplay()

if __name__ == '__main__':
    tui = urwid.curses_display.Screen()
    screen = Screen(tui)
    tui.run_wrapper(screen.run)



Can anybody point me in the right direction on how to accomplish this?

Thanks!
Dominic




More information about the Urwid mailing list