This article mainly introduces the simple Python curses library usage tutorial. it is from the IBM official Developer Technical Documentation. if you need it, you can refer to the curses library (ncurses) it provides a terminal-independent method for controlling character screens. Curses is a standard part of most UNIX-like systems (including Linux) and has been ported to Windows and other systems. The curses program runs on plain text systems, xterm, and other window-based console sessions, which makes these applications highly portable.
Introduction to curses
Python's standard curses provides basic interfaces for common features of the "glass teletype" (called CRT when the original curses library was just created in 1970s. There are many ways to make interactive text-mode programs written in Python more clever. These methods are divided into two types.
On the one hand, some Python modules support all functions of ncurses (curses superset) or slang (similar but independent console Library. It is worth noting that there is an enhancement Library (encapsulated by an appropriate Python module) that allows you to add colors to the interface.
On the other hand, many advanced widgets built on curses (or ncurses/slang) add features such as buttons, menus, scroll bars, and various public interface devices. If you have seen applications developed using libraries such as Borland's TurboWindows (DOS), you will know how attractive these features are in the text mode console. The functions in the widget library can be achieved by using curses alone, but other programmers can also achieve the results on the advanced interface. See references to find links to the mentioned modules.
This article only covers the features of curses. Since the curses module is part of the standard release, you do not have to download the support library or other Python modules to find and use it (at least in Linux or UNIX systems ). Understanding the basic support provided by curses is useful, even if it is only used as the basis for understanding advanced modules. Even if you don't use other modules, it's easy to use curses alone to build a nice and practical Python text-mode application. The pre-release notes mentioned that Python 2.0 will include the enhanced version of curses, but in any case, it should be compatible with the version described here.
Applications
I will discuss the wrappers written for Txt2Html (text-to-HTML conversion program introduced in "cute Python: My first Web-based filtering proxy, as the test application in this article. Txt2Html can be run in several ways. However, to be consistent with the purpose of this article, we will study the Txt2Html running from the command line. One way to operate Txt2Html is to provide it with a set of command line variables (which describe various aspects of the transformation to be executed), and then run the application as a batch. For occasionally used users, a more user-friendly user interface provides an interactive selection screen, which can be executed before the actual conversion, directs the user to traverse the conversion options (provide visual feedback on the selected options ).
The curses_txt2html interface is based on common top menu with drop-down and nested sub-menus. All menu-related functions are designed from scratch on curses. Although these menus lack some of the more complex features of the curses wrappers, their basic functions are implemented by several lines of code that only use curses. This interface also contains a simple scroll help box and several user input fields. The following are screen snapshots of applications that display regular la S and styles.
Applications on the X terminal
Applications on Linux terminals
Encapsulate curses applications
The basic element of curses programming is the window object. A window is an area of the actual physical screen with an addressable cursor. the coordinates of the cursor are related to the window. You can move windows around and create and delete windows without affecting other windows. In a window object, input or output operations occur on the cursor, which is usually explicitly set by the input or output method, but can also be modified separately.
After curses is initialized, you can modify or disable stream-oriented console input and output in various ways. This is basically the focus of using curses. However, once the stream console interaction is changed, if a program error occurs, the Python tracing event will not be displayed normally. Andrew Kuchling solved this problem using a good top-level framework of the curses program (see his tutorial in references ).
The following template (basically the same as that of Kuchling) retains the error reporting function in normal command line Python:
The top-level setting code of the Python [curses] program
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) will be interpreted and # a special value like curses.KEY_LEFT will be returned stdscr.keypad(1) main(stdscr) # Enter the main loop # Set everything back to normal stdscr.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 executes some initialization, calls the main () function to execute the actual work, and then executes the final clearing. If an error occurs, the mongot code block restores the console to the default state and reports an exception.
Main () event loop
Now, let's study the main () function to see what curses_txt2html does:
Curses_txt2html.py main () function and event loop
defmain (stdscr): # Frame the interface area at fixed VT100 size global screen screen = stdscr.subwin(23, 79, 0, 0) screen.box() screen.hline(2, 1, curses.ACS_HLINE, 77) screen.refresh() # Define the topbar menus file_menu = ( "File", "file_func()") proxy_menu = ( "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_menu, 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 empty rows.
The first part is the general settings of the application appearance. To establish an expected interval between application elements, the interactive area is limited to 80x25 VT100/PC screen size (even if the actual terminal window is larger ). The program draws a box around this subwindow and uses a horizontal line to draw the visual offset of the top menu bar.
The second part is the menu used to create an application. The topbar_menu () function uses some tips to bind a hotkey to an application and display the menu with the expected visual properties. Please obtain the source code file (see references) to view all the code. Topbar_menu () should be very common. (Welcome to merge it into your own application .) It is very important that once the hotkeys are bound, they are the strings contained in the second element of the menu-related byte group eval. For example, activating the "File" menu in the preceding settings calls "eval (" file_func ()")". Therefore, the application must define a function called file_func () and require it to return a Boolean value to indicate whether the application is terminated.
The third part only has two rows, but this is exactly what the entire application actually runs. The function topbar_key_handler () is like what its name implies: it waits for the keys and then processes them. The Press-key handler can return a Boolean false value. (If so, the application is terminated .) In this application, the key handler mainly checks the Keys bound to the second segment. However, even if your curses application binds a key in a different way than this application, you still need to use a similar event loop. The key part of the processing program is likely to use the following line of code:
C = screen. getch () # read a keypress
The call to draw_dict () is only the unique code in the event loop. This function draws the values in several positions in the screen window. However, in an application, you may want to use the following line of code:
Screen. refresh () # redraw the screen w/any new output
Add to the drawing/refresh function (or add only to the event loop itself ).
Get user input
The curses application obtains all user input in the form of a key event. We have read the. getch () method. now let's take a look at the example of combining. getch () with other input methods. getstr (). The following is the abbreviated version of the previously mentioned file_func () function (which 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(1,2, "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(1,2, "", hotkey_attr) s.refresh() c = s.getch() if c in (ord( 'I'), ord( 'i'), curses.KEY_ENTER, 10): 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 features. The first thing it does is to create another window object. Because the new window object is the actual drop-down menu of the "File" option, the program draws a frame around it using the. box () method. In window s, the program draws several drop-down menu options. A slightly laborious method is used to highlight the hotkeys of each option, which is compared with the rest of the option description. (Please refer to the topbar_menu () in the complete source code (see references) to learn a method that can handle highlighted display slightly automatically .) The last. addstr () call moves the cursor to the default menu option. Like the main screen, s. refresh () actually displays elements drawn to the window object.
After the drop-down menu is drawn, the program uses the simple s. getch () call to obtain the user's selection items. In the demo application, the menu only responds to the hotkey, but does not respond to the arrow keys or move the highlighted bar. You can create more complex menu functions by capturing additional key operations and setting event loops in the drop-down menu. However, this example is sufficient to describe this concept.
Next, the program compares the recently read keys with various hot key values. In this example, the drop-down menu options can be activated for the case of the hot key, and the default options can be activated by using the ENTER key. (The special key constant of curses does not seem completely reliable. I found that the actual ASCII value "10" must be added to capture the ENTER key .) Note that if you want to compare character values, you need to encapsulate the string into the built-in Python function of ord.
When the "Input" option is selected, the program uses the. getstr () method, which provides the field Input with the original editing capability (you can use the return key ). The input is terminated by the ENTER key, and the input value is returned by the method. This value is usually assigned to a variable like in the previous example.
To visually differentiate input fields, I used a little trick to add underscores to the area where data is to be input. 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 remove the underline, which is executed by the following line of code in the draw_dict () refresh function:
screen.addstr(5,33, " "*43, curses.A_NORMAL)
Conclusion
The technologies outlined here and those used in the complete application source code (see references) should give you a preliminary understanding of curses programming. Use it to compile your application. It is not difficult to use. The good news is that many languages except Python can access the curses library. Therefore, the knowledge you have learned about using the Python curses module is also applicable to other languages.
If it has been tested that the basic curses module cannot meet your requirements, the "References" section provides links to many modules. they have added the functions of curses and provided a very good development direction.