Home > Net >  How to break countdown with keyboard in python3?
How to break countdown with keyboard in python3?

Time:05-16

In the middle of some process I have a pause with countdown (for loop with time.sleep(1) inside). I'd like to be able to break it with keyboard to be able to continue earlier than countdown got finished. Is it possible with python3 (cross-platform without Linux root access)? Can I get some information about key pressed in this case ?

CodePudding user response:

Related to this question: Use getch in while (1) python

Solution: use kbhit() and getch(): https://docs.python.org/3.10/library/msvcrt.html#console-i-o

Working example:

import msvcrt
from time import sleep
def a():
    for n in range(10):
        if msvcrt.kbhit():
            return msvcrt.getch()
        sleep(1)

Note that it has a reaction delay of up to 1 second

CodePudding user response:

Here is my "cross-platform" very simplified solution.

def my_sleep(wait_sec):
    current_platform = platform.system()
    if current_platform == "Windows":
        import msvcrt

    elif current_platform == "Linux":
        import termios
        from select import select

        # save the terminal settings
        fd = sys.stdin.fileno()
        new_term = termios.tcgetattr(fd)
        old_term = termios.tcgetattr(fd)

        # switch to normal terminal
        def set_normal_term():
            termios.tcsetattr(fd, termios.TCSAFLUSH, old_term)

        # switch to unbuffered terminal
        def set_curses_term():
            termios.tcsetattr(fd, termios.TCSAFLUSH, new_term)

        def kbhit():
            dr, dw, de = select([sys.stdin], [], [], 0)
            return dr != []

        set_curses_term()
        # new terminal setting unbuffered
        new_term[3] = (new_term[3] & ~termios.ICANON & ~termios.ECHO)
        set_curses_term()

    for sec_left in range(wait_sec):
        if current_platform == 'Windows':
            if msvcrt.kbhit():
                # print(f':: {msvcrt.getch()}')
                break
        elif current_platform == 'Linux':
            if kbhit():
                ch = sys.stdin.read(1)
                # print(f'::  {ch}')
                break
        print(sec_left)
        time.sleep(1)
    
    if current_platform == "Linux":
        set_normal_term()
  • Related