0

this feels like a very trivial problem but after searching and experimenting for hours I couldn't reach a single solution.

I'm using curses to move my robot using the keyboard keys, it works as intended but for 1 thing, every time that a "getch()" is hit it executes previous pressed keys even if there is nothing being pressed, that creates a 'lag' situation.

This is a very simple scenario that I created to explain myself, in here let's say that I press 'a', which works correctly, I keep it pressed for around 4 more seconds and release, now this code will be executed again and again even if there is nothing being pressed because curses will execute it x times for all the 'a' that I pressed during the time.sleep:

import curses
import time
stdscr = None

def SetupCurses():
    global stdscr
    stdscr = curses.initscr()
    curses.cbreak()
    stdscr.keypad(1)


def StartCurse():

    key = ''
    while key != ord('q'):
        stdscr.clear()
        stdscr.refresh()
        key = stdscr.getch()
        if key == ord('a'):
            print("\nyou pressed a\n")
            time.sleep(5)
            print("\nyou can press a again\n")
            time.sleep(1)

while(True):
    SetupCurses()
    StartCurse()

So I thought, well, I didn't want to do that but I will completely kill curses and connect it again before checking for keys, but even after doing that curses seem to be picking up keys that it shouldn't (and I really dislike this approach anyway, I feel like I shouldn't need to shut it down like this if I will use it again and again), this scenario will have the same problem of the scenario above:

import curses
import time
stdscr = None

def SetupCurses():
    global stdscr
    stdscr = curses.initscr()
    curses.cbreak()
    stdscr.keypad(1)


def StartCurse():

    key = ''
    while key != ord('q'):
        stdscr.clear()
        stdscr.refresh()
        key = stdscr.getch()
        if key == ord('a'):
            break

def EndCurse():
    global stdscr
    curses.nocbreak()
    stdscr.keypad(False)
    curses.echo()
    curses.endwin()
    stdscr = None

while(True):  
    SetupCurses()

    print("\nyou can press a again\n")
    time.sleep(1)

    StartCurse()  
    EndCurse()

    time.sleep(5)
    print("\nyou pressed a\n")

My question is: is there some sort of code that does:

curses.ClearAnyPreviousInput()
ThisKeyIsBeingPressedRightNow = stdscr.getch()

if possible something that doesn't force me to kill and restart everything again

pau Fer
  • 130
  • 7
  • i'm not sure but some systems or languages (or maybe consoles) had function to set delay before system start repeating key - and maybe it would stop repeating it. In other question for C/C++ code I saw `while` loop which get char and compare with previous value until it get new value. https://stackoverflow.com/a/47191009/1832058 I would also check if `stdscr` has something to clear buffer. – furas May 27 '20 at 20:15
  • 1
    Maybe try [curses.flushinp](https://docs.python.org/2/library/curses.html#curses.flushinp) – furas May 27 '20 at 20:29

1 Answers1

1

It seems you need curses.flushinp()

Flush all input buffers. This throws away any typeahead that has been typed by the user and has not yet been processed by the program.


Eventually you can try to remove repeated keys

new_key = stdscr.getch()

while new_key == key:
      new_key = stdscr.getch()

key = new_key

(found in C code in answer for Configure key repeat delay to detect if key is being pressed)

furas
  • 134,197
  • 12
  • 106
  • 148
  • yes! I don't understand how on earth I didn't come across to that after so much googling, but seems to do exactly what I'm asking for – pau Fer May 27 '20 at 20:36
  • I found it only because I was searching `flush()` which is used in some buffers to remove or send data. – furas May 27 '20 at 20:39