Although there is a fair choice of GUI libraries for Python (good overview of Python GUI libraries is here), sometimes we need just a little bit more enhanced terminal interface, like in my recent project – XMPP test client – where requirements were quite simple – just to split terminal screen into two areas – main screen where messages are displayed (possibly asynchronously) and bottom line, where commands/messages can be entered:
In Python we have couple of options for terminal UI programming:
- curses – curses library is part of standard python distribution, it provides lower level access to terminal programming and terminal control sequences. Many things are left to users – like resizing UI, event loops etc.
- urwid – is an excellent external library, which provides higher level interfaces for programming terminal UIs. It’s a bit similar to above mentioned GUI kits, providing widgets, layout managers, event loop etc. And many common tasks missing in curses are already included.
I decided to use urwid, because it looked easier to start with and many required functionalities were already provided (like already mentioned resizing, which I think would be pretty tedious to re-implement in curses). I’ve created simple commander module, which provides interface similar to build-in cmd.Cmd, but with UI layout as shown above. With this module we can create simple tools very easily:
if __name__=='__main__':
class TestCmd(Command):
def do_echo(self, *args):
'''echo - Just echos all arguments'''
return ' '.join(args)
def do_raise(self, *args):
raise Exception('Some Error')
c=Commander('Test', cmd_cb=TestCmd())
#Test asynch output - e.g. comming from different thread
import time
def run():
while True:
time.sleep(1)
c.output('Tick', 'green')
t=Thread(target=run)
t.daemon=True
t.start()
#start main loop
c.loop()
Which creates tool like this:


Fantastic! Worked great for a chat client I was writing 🙂
I have to say that this is soooooo cool!!! Exactly what I am looking for!
Thanks!
When I pressed UP key, the texts in the input bar at the bottom of the terminal changes to last command I typed, as was expected. But, the cursor appears at the beginning of the line, and I want it to be at the ending of the line. Any ways to do that?
I’m a Chinese native speaker, never mind if there are errors in this comment 😉
Thank you very much!
Add
self.set_edit_pos(len(self.edit_text))after
self.edit_text=self.history[self._history_index]I should read your code before asking the question… I’m sorry that I had not noticed your reply ‘coz I thought I will be notified (via Email). However, thank you very much, that worked!