使用空格键

时间:2017-08-12 17:21:55

标签: python macos timer sleep

说我想要花多长时间屏住呼吸,我想用Python做到这一点。我有简短的剧本:

start = time()
try:
    while True: pass
except KeyboardInterrupt:
    print(time() - start)

这具有我想要的基本功能,但它有致命缺点。经过长时间的屏住呼吸,我的思绪可能有点模糊,我可能无法立即按Ctrl + c找到协调,我可能会丢失有关我训练的重要数据。

空格键更容易击中目标。当我按下它时,是否有一种简单的方法可以使循环停止?

编辑:我在OSX上

3 个答案:

答案 0 :(得分:1)

您需要将控制台的键盘(pty)驱动程序置于原始模式。 答案中解释了这一点:What is the easiest way to detect key presses in python 3 on a linux machine?

从那个答案中大肆引用:

#! /usr/bin/env python3
import sys
import termios
import time
import tty


def hold_breath(fin):
    orig_setting = termios.tcgetattr(fin)
    tty.setraw(fin)
    start = time.time()
    try:
        ch = fin.read(1)[0]
        assert ch == ' '
    finally:
        print('You lasted %.03f seconds.\r' % (time.time() - start))
        termios.tcsetattr(fin, termios.TCSADRAIN, orig_setting)


if __name__ == '__main__':
    print('Hit space.')
    hold_breath(sys.stdin)

在OS / X和Linux上正常运行。如果您在恢复原始设置之前最终中断了该程序,那么$ stty sane就是您的朋友。

答案 1 :(得分:1)

答案取决于您的操作系统。在Windows上,这将在任何按键时停止,但您可以查看msvcrt.getch()的返回值以确定它是否为空格。现在,当你昏倒时,你的脸击中了键盘,它将停在任何键上。

import time
import msvcrt
start = time.time()
while not msvcrt.kbhit():  # Indicates a key is waiting to be read
    pass
end = time.time()
msvcrt.getch()  # read and (in this case) throw away the key press.
print(end-start)

答案 2 :(得分:0)

import sys                                                                          
import termios                                                                      
import contextlib                                                                   

SPACE_BAR = 32                                                                      

@contextlib.contextmanager                                                       
def raw_mode(file):                                                                 
    old_attrs = termios.tcgetattr(file.fileno())                                    
    new_attrs = old_attrs[:]                                                        
    new_attrs[3] = new_attrs[3] & ~(termios.ECHO | termios.ICANON)                  
    try:                                                                            
        termios.tcsetattr(file.fileno(), termios.TCSADRAIN, new_attrs)              
        yield                                                                       
    finally:                                                                        
        termios.tcsetattr(file.fileno(), termios.TCSADRAIN, old_attrs)              


def main():                                                                         
    print 'exit with spacebar'                                                      
    with raw_mode(sys.stdin):                                                       
        try:                                                                        
            while True:                                                          
                if sys.stdin.read(1) == chr(SPACE_BAR):                          
                    break                                                        

        except (KeyboardInterrupt, EOFError):                                    
            pass                                                                 


if __name__ == '__main__':                                                       
    main()