Python text terminal GUI framework, cool

Today, the author will show you some common UI frameworks based on text terminals!


The first one is Curses[1].

Curves is a dynamic library that can provide text-based terminal window functions. It can:

  • Use entire screen
  • Create and manage a window
  • Use 8 different colors
  • Provide mouse support for programs
  • Using the function keys on the keyboard

Curves can run on any Unix/Linux system that follows the ANSI/POSIX standard. You can also run on Windows, but you need to install the Windows Curses library additionally:

pip install windows-curses

The picture above is a Tetris game [2] written by a friend with curves. I don't feel full of memories. I can take it to revive the antique machine.

Let's also try ox knife:

import curses

myscreen = curses.initscr()

myscreen.addstr(12, 25, "Python curses in action!")

  • Note that the first two parameters of addstr are character coordinates, not pixel coordinates
  • getch blocks the program until it waits for keyboard input
  • Curses Endwin() is used to exit the window
  • If you need to continuously listen to user interaction, you need to write a loop and judge the input obtained by getch()

The code runs as follows:

Curves is very lightweight, especially suitable for handling simple interaction and replacing complex parameter input programs. It is elegant and simple, and curves is also the basis of other text terminal UI.


Npyscreen[3] is also a Python component library for writing text terminals. It is an application framework based on curves.

Compared with curves, Npyscreen is closer to UI programming. It completes UI presentation and interaction through the combination of components, and Npyscreen can adapt to screen changes.

Npyscreen provides multiple controls, such as Form, TitleText, TitleDateCombo, MultiLineEdit, TitleSelectOne, and TitleSlider.

It provides powerful functions to meet the requirements of rapid program development, whether it is a simple single page program or a complex multi page application.

Let's take a small example:

import npyscreen

class TestApp(npyscreen.NPSApp):
    def main(self):
        # These lines create the form and populate it with widgets.
        # A fairly complex screen in only 8 or so lines of code - a line for each control.
        F  = npyscreen.Form(name = "Welcome to Npyscreen",)
        t  = F.add(npyscreen.TitleText, name = "Text:",)
        fn = F.add(npyscreen.TitleFilename, name = "Filename:")
        fn2 = F.add(npyscreen.TitleFilenameCombo, name="Filename2:")
        dt = F.add(npyscreen.TitleDateCombo, name = "Date:")
        s  = F.add(npyscreen.TitleSlider, out_of=12, name = "Slider")
        ml = F.add(npyscreen.MultiLineEdit,
               value = """try typing here!\nMutiline text, press ^R to reformat.\n""",
               max_height=5, rely=9)
        ms = F.add(npyscreen.TitleSelectOne, max_height=4, value = [1,], name="Pick One",
                values = ["Option1","Option2","Option3"], scroll_exit=True)
        ms2= F.add(npyscreen.TitleMultiSelect, max_height =-2, value = [1,], name="Pick Several",
                values = ["Option1","Option2","Option3"], scroll_exit=True)

        # This lets the user interact with the Form.


if __name__ == "__main__":
    App = TestApp()
  • The Npyscreen module is introduced. If it is not available, it can be installed through pip: pip install npyscreen
  • Inherit npyscreen Npsapp creates an application class TestApp
  • Implement the main method, which creates a Form object, adds various controls to the Form object, and sets some properties of the controls
  • Call the Edit method of the form object to hand over the operation right to the user
  • At runtime, instantiate the TestAPP, and then call the run method to start the application. The application can enter the state of waiting for user interaction

The effect of the above code is as follows:


  • [Tab] / [Shift + Tab] for switching control focus
  • [Enter] / [space] is used to enter selection, setting and confirmation
  • In the selection frame, the direction keys are similar to vim[4], that is, they are controlled through hjkl

Isn't it amazing that so many complex operations can be done with text? Are the previous doubts about the progress display in the command line clear~


If Curses and Npysreen are lightweight text terminal UI frameworks, Urwid[5] is definitely a heavyweight player.

Urwid includes many features for developing text UI, such as:

  • Apply window adaptation
  • Text auto align
  • Easily set up text blocks
  • Powerful selection box control
  • It can be integrated with various event driven frameworks, such as Twisted[6], Glib[7], Tornado[8], etc
  • Provides a variety of prefabricated controls such as edit boxes, buttons, multiple (single) selection boxes, etc
  • The display mode supports native, curves mode, LCD display and network display
  • Support UTF-8 and CJK character set (Chinese can be displayed)
  • Supports multiple colors

See the effect:

I don't know how you feel after reading it. My feeling is: it's too voluminous~

Can do almost everything under the GUI!

What's more, Urwid is completely based on the object-oriented idea:

Now let's have a try and feel the power of Urwid:

import urwid

def show_or_exit(key):
    if key in ('q', 'Q'):
        raise urwid.ExitMainLoop()

txt = urwid.Text(u"Hello World")
fill = urwid.Filler(txt, 'middle')
loop = urwid.MainLoop(fill, unhandled_input=show_or_exit)
  • First introduce the urwid module
  • Defines an input event handling method, show_or_exit
  • In the processing method, when the input key is Q or Q, exit the main cycle, otherwise the key name will be displayed
  • Urwid Text is a text control that accepts a string as the display information
  • Urwid Filler is similar to panel. It fills the txt control on it and sets the position in the center of the window
  • Urwid Mainloop sets the main loop of urwid, takes fill as the drawing entry of the control, and the parameter unhandled_input accepts a key event processing method, using the previously defined show_or_exit
  • Loop Run() starts the UI and monitors various events

Running this code, you can see that the command line is set to interactive mode. When you press the key, the key name will be displayed in the center of the window. If you press the q key, the program will exit.

Urwid can only run in the Linux operating system. Windows cannot run because of missing necessary components


Due to space limitations, only three text terminal frameworks are shown here, but we can already have a strong feeling about the UI framework based on text terminal.

There are also some excellent frameworks, such as prompt_toolkit, interested students can study it.

Although the UI based on text terminal is not the mainstream for a long time, it still has its value in some special industries or businesses. Research may help us in special places.

Finally, I recommend an interesting application based on text terminal - command line Netease cloud music [9]:

It is developed based on curves. If it runs, it can be shocked by its strength. If you have time, you can play. Compare your heart!

Tags: Python UI GUI

Posted by laura_richer on Mon, 30 May 2022 21:02:41 +0530