Simple Python curses library use tutorial

Source: Internet
Author: User
Tags ord home screen python curses
The Curses Library (ncurses) provides a terminal-independent method for controlling character screens. Curses is a standard part of most UNIX-like systems, including Linux, and it has been ported to Windows and other systems. The curses program runs on plain text systems, xterm, and other windowing console sessions, making these applications well-portable.
Introduction Curses

Python's standard curses provides the "glass telex" (Glass teletype) (in the 1970s, when the original curses library was just created, it is called the CRT) 's basic interface for common features. There are many ways to make interactive text schema programs written in Python more ingenious. These methods fall into two categories.

On the one hand, some Python modules support the full set of features of the ncurses (curses superset) or slang (similar but independent console libraries). Most notably, there is an enhanced library (encapsulated by the appropriate Python module) that allows you to add colors to the interface.

On the other hand, many of the advanced widget libraries built on curses (or Ncurses/slang) add features such as buttons, menus, scroll bars, and various common interface devices. If you've seen applications developed with libraries such as Borland's Turbowindows (DOS), you know how appealing these features are in the text-mode console. The features in the Widget Gallery can be achieved using curses alone, but can also take advantage of the results that other programmers have achieved on the advanced interface. See Resources for links to the modules that are mentioned.

This article only deals with the characteristics of curses itself. Since the curses module is part of a standard release, you can find and use it (at least on Linux or UNIX systems) without having to download a support library or other Python module. Understanding the basic support provided by curses is useful, even if only as a basis for understanding advanced modules. Even without the use of other modules, it is easy to build beautiful and useful Python text-mode applications using curses alone. The pre-release note mentions that Python 2.0 will include an enhanced version of curses, but it should be compatible with the version described here anyway.

Application

I'll discuss the wrapper that was written for txt2html (the text-to-HTML translator described in "cute Python: My first Web-based filtering agent") as the test application for this article. Txt2html has several operating modes. But to be consistent with the purpose of this article, we will look at the txt2html running from the command line. One way to manipulate txt2html is to provide it with a set of command-line variables that describe aspects of the transformation to be performed, and then run the application as a batch process. For occasional users, a more user-friendly interface provides an interactive selection screen that guides the user through the conversion options (visual feedback with the selected option) before performing the actual conversion.

The Curses_txt2html interface is based on a common top-bar menu with drop-down and nested submenus. All menu-related features are designed "from scratch" on curses. Although these menus lack some of the features of a more complex curses wrapper, their basic functionality is implemented by a few lines of code that use only curses. This interface also comes with a simple scrolling help box and several user input fields. The following is a screenshot of the application that displays the general layout and style.
Applications on the X terminal

Applications on Linux Endpoints

Encapsulating curses applications

The basic element of curses programming is the Window object. The window is the area of the actual physical screen with an addressable cursor, and the coordinates of the cursor are related to the window. You can move windows around, and you can create and delete windows without affecting other windows. In a Window object, an input or output operation occurs on the cursor, which is usually explicitly set by the input or output method, but can also be modified individually.

After initializing curses, you can modify or completely disable stream-oriented console input and output in a variety of ways. This is basically the whole point of using curses. However, once the streaming console interaction is changed, if the program goes wrong, the Python retrospective event will not be displayed in the normal way. Andrew Kuchling solves this problem with a good curses program top-level framework (see Resources for his tutorial).

The following template (essentially the same as kuchling) retains the error reporting functionality of the normal command line Python:
Top-level Setup code for Python [curses] Programs

Import   curses, Traceback  if   __name__==  ' __main__ ':  try  :   # Initialize Curses stdscr= CURSES.INITSCR ()   # Turn off echoing of keys, and enter Cbreak mode,   # where no buffering is performed on keyboard Input Curses.noecho () Curses.cbreak ()   # in keypad mode, escape sequences for special keys   # (like the cursor keys would be interpreted and   # A special value like curses. Key_left'll be returned Stdscr.keypad (1) Main (STDSCR)   # Enter The main loop   # Set everything back to normal St Dscr.keypad (0) Curses.echo () Curses.nocbreak () Curses.endwin ()   # Terminate curses  except  :   # in Event of error, restore terminal to sane state. Stdscr.keypad (0) Curses.echo () Curses.nocbreak () Curses.endwin () Traceback.print_exc ()   # Print the exception

The try code block performs some initialization, invokes the main () function to perform the actual work, and then performs the final cleanup. If an error occurs, the except code block restores the console to its default state, and then reports the exception that was encountered.

Main () event loop

Now, let's examine the main () function and see what curses_txt2html does:
curses_txt2html.py main () function and event loop

Defmain  (STDSCR):  # Frame The interface area at fixed VT100 size  global screens Screen   = Stdscr.subwin (23, , 0, 0) screen.box () Screen.hline (2, 1, curses. Acs_hline, Screen.refresh)  # Define the Topbar menus file_menu = (  "file",  "File_func ()") Proxy_menu = ( c7/> "Proxy Mode",  "Proxy_func ()") Doit_menu = (  "Do it!",  "Doit_func ()") Help_menu = (  "Help"  , "Help_func ()") Exit_menu = (  "Exit",  "Exit")  # ADD The Topbar menus to screen object Topbar_menu (file_men U, Proxy_menu, Doit_menu,     Help_menu, Exit_menu)  # Enter the Topbar menu loop while   Topbar_key_ Handler ():  draw_dict ()

The main () function is easy to understand based on the three parts separated by a blank line.

The first section performs general settings for the appearance of the application. To establish an expected interval between application elements, the interactive region is limited to a vt100/pc screen size (even if the actual terminal window is larger). The program draws a box around this subwindow and uses horizontal lines to draw the visual offset of the top bar menu.

The second part establishes the menu used by the application. The function Topbar_menu () uses some tricks to bind a hotkey to an application operation and display the menu with the desired visual properties. Please get the source file (see Resources) to see all the code. Topbar_menu () should be very common. (You are welcome to merge it into your own application.) It is very important that once a hotkey is bound, they will be eval () the string contained in the second element of the menu-related byte group. For example, activating the "File" menu in the above settings will call "eval (" File_func () "). Therefore, the application is required to define a function called File_func (), which requires it to return a Boolean (Boolean) value to indicate whether the application termination state is reached.

The third part has only two lines, but that's exactly what the entire application is actually running. The function Topbar_key_handler () is like its name implies: it waits for keystrokes and then processes them. The keystroke handler can return a Boolean false value. (If this is the case, the application terminates.) In the application, the key handler is primarily to check the key that is bound in the second paragraph. But even if your curses application binds the key in a different way than the application, you'll still want to use a similar event loop. The key part of the handler is likely to use the following line of code:

c = Screen.getch () # Read a keypress

The call to Draw_dict () is only the only code in the event loop. This function draws the values in several places in the screen window. But in the application, you might want to put the following line of code:

Screen.refresh () # Redraw the screen w/any new output

Added to the Draw/refresh function (or only to the event loop itself).

Get user input

The curses application obtains all user input in the form of a keystroke event. We've already seen the. Getch () method, now let's take a look at the example of combining. Getch () with other input methods. GETSTR (). Here is an abbreviated version of the File_func () function we mentioned earlier (it is activated by the "File" menu).
curses_txt2html.py File_func () function

Deffile_func  (): s = Curses.newwin (5,10,2,1) S.box () s.addstr (  "I", hotkey_attr) s.addstr (1,3,  "Nput" , menu_attr) s.addstr (2,2,  "O", hotkey_attr) s.addstr (2,3,  "Utput", menu_attr) s.addstr (3,2,  "T", Hotkey_ attr) S.addstr (3,3, "  ype", menu_attr) s.addstr ("  " ", Hotkey_attr) S.refresh () c = S.getch ()   if   C  inch   (Ord (  ' I '), Ord (  ' I '), curses. Key_enter:  curses.echo ()  s.erase ()  screen.addstr (5,33,  "" *43, curses. A_underline)  cfg_dict[  ' source '] = Screen.getstr (5,33)  Curses.noecho ()   else  :  Curses.beep ()  s.erase ()   return   CONTINUE

This function combines several curses attributes. The first thing it does is create another window object. Because this new Window object is the actual drop-down menu for the "File" selection, the program uses the. box () method to draw a frame around it. In Windows S, the program draws several drop-down menu options. A slightly laborious approach is used to highlight the hotkey for each option, which contrasts with the rest of the option description. (See Topbar_menu () in the full source code (see Resources) to learn a way to handle highlighting slightly automatically.) The last. Addstr () call moves the cursor to the default menu option. Like the home screen, S.refresh () actually shows the elements that are drawn to the Window object.

After drawing the drop-down menu, the program uses a simple S.getch () call to get the user's selection. In the demo application, the menu responds to the hotkey only, but does not respond to the arrow keys or to the movable highlight bar. These more complex menu functions can be built by capturing additional key actions and setting the event loop in the drop-down menu. But this example is enough to illustrate the concept.

The program then compares the keystrokes that have just been read to the various hotkey values. In this case, the case of the hotkey activates the drop-down menu option, and you can use the ENTER key to activate the default option. (Curses special key constants do not look completely reliable, I found that I had to add the actual ASCII value "10" to catch the Enter key.) Note that if you are performing a character-value comparison, wrap the string into the Ord () built-in Python function.

When the input option is selected, the program uses the. GETSTR () method, which provides field input with the original editing capability (you can use the backspace bar). The input is terminated by the ENTER key, and the method returns the value entered. This value is usually assigned to a variable, as in the previous example.

In order to visually differentiate the input fields, I used a little bit of finesse to pre-underline the area where the data input will occur. In any case, this is necessary, but it adds a visual effect. Underline the following line of code:

Screen.addstr (5,33, "" *43, curses. A_underline)

Of course, the program must also remove the underscore, which is done in the draw_dict () Refresh function by the following line of code:

Screen.addstr (5,33, "" *43, curses. A_normal)

Conclusion

The techniques outlined here and the techniques used in the full application source code (see Resources) should give you an initial understanding of curses programming. Please use it to write your application. It is not difficult to use. To tell you the good news, in addition to Python, there are many languages that can access the curses library, so the knowledge you learned to use the Python curses module also applies to other languages.

If the basic curses module does not meet your requirements after testing, the "References" section provides links to a number of modules that add functionality to the curses and provide a very good development direction.

  • Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.