Python is an interpreted, high level language that is freely available for
developing applications. And Curses or ncurses is a library that lets you
program GUIs in Python. Curses library is about window programming within the
boundaries of the terminal. Using this library one can manipulate data, create a
sub window or create multiple windows of all sizes that overlap. A programmer
can use colors, mouse pointer, etc on screen even if the 'X' server (in Linux or
Unix) is not running. For eg, when you're logged in to Linux on a terminal where
neither X is installed nor you have the privilege to run it; you can use Curses
to write applications which can directly run on the terminal with Mouse and
color support.
Although Curses is mostly used in 'C' language (as ncurses.h) for making
suitable GUIs, in Python it helps programmers to develop applications in a
simpler way. A lot of components such as buttons, menus and scroll bars are made
using Curses. In this article, we discuss the basic concepts for using Curses in
Python.
Direct Hit! |
Applies To: Python developers USP: Build GUI with Curses Primary Link: www.amk.ca/ python/howto/curses Keywords: curses in python |
Prerequisites
Check if your system has Python installed, by issuing the following command
in openSUSE or Fedora:
# rpm -q python
If the command output is “python-2.5.1-39,” it means Python version 2.5 is
installed on the system. And if the system prompts “package python is not
installed” then you have to install it by issuing the following command:
# yast -i python (for openSUSE)
# yum install python (for Fedora)
Using Curses
The following steps show what processes take place from start till the end
of a Curses application:
1. Import Curses library to Python (in our case).
2. Initialize Curses.
3. Create one or more windows, as per need.
4. Manipulate windows for user input and output.
5. Close the open windows & stop Curses
Let's start with a simple example where we shall import Curses library to our
Python programs and initialize those. First open the terminal and issue 'vi
curses.py' command to start the text editor and change to insert mode by
pressing the 'I' key. This is how you write it (ignore the numbers):
1. import curses
2. stdscr = curses.initscr()
Now save the file and exit from the text editor by pressing 'esc' button.
Then write “:wq” and press enter. Initialization of the terminal is necessary
because when Curses starts, it gives you a completely new window to work on. And
when you exit, ie stop Curses then everything should be brought back to the
previous state. After it saves the terminal state it automatically calls the
subroutine named 'setupterm' which sets up a new terminal, independent of the
previous terminal for curses.
Windowing with Curses
A window in Curses can have any display size and even be a single character
long. As in other programming languages variables are defined for each data
type, similarly in Curses, variables are declared for each kind of window.
Whenever a window is created, its structure is stored in the memory,
specifically allocated for the newly created window. So, whenever changes are
done to a window, they get reflected in the memory and one has to explicitly use
“refresh()” to update the physical screen display.
Virtually, whenever you initialize Curses, a default window called “stdscr”
is created, which has the same height and width as the terminal.
Apart from main windows, there are sub windows as well. These windows reside
within a window that has already been created. To create a window, add the
following line to your program:
1. s = stdscr.subwin(23, 79, 0, 0)
2. s.box()
3. s.refresh()
In the above code, the first line specifies the coordinate on the screen
where the rectangular box will be drawn. The parameters are height, weight and
Y, X coordinates. Note that unlike other programming parameters, here the Y
coordinate is specified before the X coordinate. Next is the box subroutine
which draws a box in memory and finally refreshes it to make changes to the
physical display device.
Pad is another class of windows which is not restricted by the size of the
terminal or the physical display device. And only a part of the pad can be
viewed at a given time, similar to viewing a full size 1600x1600 (say)
resolution picture on the picture viewer. In case of a normal window you need to
refresh the whole window but here only the portion which is visible, needs to be
refreshed.
Pads are used where multiple window are created to do certain tasks, because
when you do 'refresh()' for a particular window, the rest of the windows flicker
unnecessarily. Just as in windows we have a sub window, here we have subpads.
Creating a pad is slightly different than creating a window and can be done
through the following code:
1. pad = curses.newpad(100, 100)
2. for y in range(0, 100):
3. for x in range(0, 100):
4. pad.addch(y,x, ord('a') + (x*x+y*y) % 26 )
5. pad.refresh( 0,0, 5,5, 20,75)
First the Pad's height and width is provided and then for displaying the pad,
the on screen coordinate is provided. So in the refresh section, the pad's
coordinate (portion of the pad to be displayed) and the on-screen area are
provided, i.e. starting yx coordinate and the ending yx coordinate.
Terminating Curses
After all the required work has been done, you need to end the Curses
process and return to initial state. As discussed, the initial state is already
saved. So to end Curses and to return to the initial state, write the following
code at the end of your program:
curses.endwin()
In this article we have covered the basics of Curses. More details shall be
covered in subsequent articles.