Search code examples
pythonmacosterminal

not able to check a key pressed in Python on macOS without echo


In Python, I wanted to detect a key is pressed without using non-standard third-party libs, on macOS. Here is my test code:

import select
import sys
import termios
from time import sleep

def is_key_pressed():
    fd = sys.stdin.fileno()
    old_settings = termios.tcgetattr(fd)

    try:
        new_settings = termios.tcgetattr(fd)
        new_settings[3] = new_settings[3] & ~(termios.ECHO | termios.ICANON)
        termios.tcsetattr(fd, termios.TCSADRAIN, new_settings)

        ready, _, _ = select.select([sys.stdin], [], [], 0)
        return sys.stdin in ready
    finally:
        termios.tcsetattr(fd, termios.TCSAFLUSH, old_settings)

def main():
    print("Testing select:")
    sleep_time = 1 / 60

    while True:
        sleep(sleep_time)
        if is_key_pressed():
            break

if __name__ == "__main__":
    main()

It actually detects key pressed. But there is a problem: the input char is echoed. I tried to disable the echo by disabling termios.ECHO but it seems not working.

Here is the output of the test on macOS:

$ python test.py
Testing select:
1%                    

(Pressed the key '1' during the test). A second question is: why is there a % shown at the end ?

What I wanted: no echo of '1', nor '%'.


Solution

  • Turning echo on and off during the loop allows the user to type ahead while echo is on, and their input will be echoed.

    Turn echo off before the loop, and turn it back on when the loop is done.