BANGALORE, INDIA: 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.
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.