user4805123
user4805123

Reputation:

Curses keypad(True) does not get special keys

I am trying to write code for both Python 2 and 3. Here is my complete code that I am using to learn curses:

# -*- coding: utf-8 -*-
from __future__ import print_function

import curses
import sys
import traceback


class Cursor(object):
    def __init__(self):
        self.stdscr = curses.initscr()
        curses.noecho()
        curses.cbreak()
        self.stdscr.keypad(True)

    def end_window(self):
        curses.nocbreak()
        self.stdscr.keypad(False)
        curses.echo()
        curses.endwin()

    def start_win(self, begin_x=0, begin_y=1, height=24, width=71):
        return curses.newwin(height, width, begin_y, begin_x)


def applic():
    print("yo man")
    x = Cursor()
    window = x.start_win()
    try:
        # This raises ZeroDivisionError when i == 10.
        for i in range(0, 11):
            v = i - 10
            key = window.getch()
            # EDIT - Added this debug line to verify what key gets
            window.addstr('type of {} is {}\n'.format(key, type(key)))
            if key == curses.KEY_UP:
                return
            window.addstr('10 divided by {} is {}\n'.format(v, 10 // v))
            window.refresh()

    except Exception:
        x.end_window()
        errorstring = sys.exc_info()[2]
        traceback.print_tb(errorstring)

applic()

My problem is that key will never equal curses.KEY_UP because getch() (or getkey()) is returning single character strings, not the entire escape key code that equals KEY_UP (\x1b]A). So each time I press the up arrow in the routine, the program cycles through the three parts of the key code \x1b, [, A, and producing three lines of output:

10 divided by -10 is -1
10 divided by -9 is -2
10 divided by -8 is -2

for this test, I want the UP arrow key to allow me to break out before the expected exception that will occur when i equals 10.

According to the python documentation for Curses, stdscr.keypad(True) is supposed to allow returning the entire key code, but does not appear to do so.

Added some debugging printout information to show what is coming back. Whether I use getch() or getkey(), the result is the same; it returns a string (the documentation indicated that an integer would be returned for getch):

type of ^[ is <class 'str'>
10 divided by -9 is -2
type of [ is <class 'str'>
10 divided by -8 is -2
type of A is <class 'str'>
10 divided by -7 is -2

Upvotes: 0

Views: 2074

Answers (1)

Thomas Dickey
Thomas Dickey

Reputation: 54465

The problem is that you set the keypad property on the main window, but are reading from a different window using getch. This change would make your program accept a KEY_UP:

--- curses-vs-keypad.py 2017/04/02 11:07:41     1.1
+++ curses-vs-keypad.py 2017/04/03 00:57:16
@@ -28,6 +28,7 @@
     print("yo man")
     x = Cursor()
     window = x.start_win()
+    window.keypad(True)
     try:
         # This raises ZeroDivisionError when i == 10.
         for i in range(0, 11):

Upvotes: 2

Related Questions