web-dev-qa-db-ja.com

Pythonが押されたキーを待つようにするにはどうすればいいですか?

ユーザーがキーを押すまでスクリプトを待機させます。

それ、どうやったら出来るの?

452
Janusz

Python 3では、raw_input()は存在しません。だから、ちょうど使用:

input("Press Enter to continue...")

Python 2では、raw_input()input(Prompt)と同等であるため、eval(raw_input(Prompt))を使用してください。

raw_input("Press Enter to continue...")

これは、ユーザーがEnterキーを押すのを待つだけなので、 msvcrt を使用することをお勧めします。 MSVCRT)):

import msvcrt as m
def wait():
    m.getch()

これはキーが押されるのを待つはずです。

400
riza

Python 2でこれを行う1つの方法は、raw_input()を使用することです。

raw_input("Press Enter to continue...")

Python3ではそれはただinput()です

314
Greg Hewgill

私のLinuxマシンでは、次のコードを使います。これは私が他のところで見たコードと似ています(例えば、古いpython FAQsで)、このコードはタイトなループの中で回転します。コードはありません。

def read_single_keypress():
    """Waits for a single keypress on stdin.

    This is a silly function to call if you need to do it a lot because it has
    to store stdin's current setup, setup stdin for reading single keystrokes
    then read the single keystroke then revert stdin back after reading the
    keystroke.

    Returns a Tuple of characters of the key that was pressed - on Linux, 
    pressing keys like up arrow results in a sequence of characters. Returns 
    ('\x03',) on KeyboardInterrupt which can happen when a signal gets
    handled.

    """
    import termios, fcntl, sys, os
    fd = sys.stdin.fileno()
    # save old state
    flags_save = fcntl.fcntl(fd, fcntl.F_GETFL)
    attrs_save = termios.tcgetattr(fd)
    # make raw - the way to do this comes from the termios(3) man page.
    attrs = list(attrs_save) # copy the stored version to update
    # iflag
    attrs[0] &= ~(termios.IGNBRK | termios.BRKINT | termios.PARMRK
                  | termios.ISTRIP | termios.INLCR | termios. IGNCR
                  | termios.ICRNL | termios.IXON )
    # oflag
    attrs[1] &= ~termios.OPOST
    # cflag
    attrs[2] &= ~(termios.CSIZE | termios. PARENB)
    attrs[2] |= termios.CS8
    # lflag
    attrs[3] &= ~(termios.ECHONL | termios.ECHO | termios.ICANON
                  | termios.ISIG | termios.IEXTEN)
    termios.tcsetattr(fd, termios.TCSANOW, attrs)
    # turn off non-blocking
    fcntl.fcntl(fd, fcntl.F_SETFL, flags_save & ~os.O_NONBLOCK)
    # read a single keystroke
    ret = []
    try:
        ret.append(sys.stdin.read(1)) # returns a single character
        fcntl.fcntl(fd, fcntl.F_SETFL, flags_save | os.O_NONBLOCK)
        c = sys.stdin.read(1) # returns a single character
        while len(c) > 0:
            ret.append(c)
            c = sys.stdin.read(1)
    except KeyboardInterrupt:
        ret.append('\x03')
    finally:
        # restore old state
        termios.tcsetattr(fd, termios.TCSAFLUSH, attrs_save)
        fcntl.fcntl(fd, fcntl.F_SETFL, flags_save)
    return Tuple(ret)
50
mheyman

システムコマンドに依存して問題なければ、以下を使用できます。

Linux:

os.system('read -s -n 1 -p "Press any key to continue..."')
print

Windows:

os.system("pause")
27
CrouZ

単に使う

input("Press Enter to continue...")

構文解析中にSyntaxError:expected EOFが発生します。

簡単な修正方法

try:
    input("Press enter to continue")
except SyntaxError:
    pass
23
alltrue

Python manual は以下を提供します。

import termios, fcntl, sys, os
fd = sys.stdin.fileno()

oldterm = termios.tcgetattr(fd)
newattr = termios.tcgetattr(fd)
newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
termios.tcsetattr(fd, termios.TCSANOW, newattr)

oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)

try:
    while 1:
        try:
            c = sys.stdin.read(1)
            print "Got character", repr(c)
        except IOError: pass
finally:
    termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
    fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)

あなたのユースケースにロールインすることができます。

14
Jaap Versteegh

プラットフォームに依存しない方法はわかりませんが、Windowsでは、msvcrtモジュールを使用すれば、そのgetch関数を使用できます。

import msvcrt
c = msvcrt.getch()
print 'you entered', c

mscvcrtには、キーが待たずに押されたかどうかを確認するためのノンブロッキングのkbhit()関数も含まれています(対応するcurses関数があるかどうかは不明)。 UNIXにはcursesパッケージがありますが、すべての画面出力に使用しなくても使用できるかどうかはわかりません。このコードはUNIX上で動作します。

import curses
stdscr = curses.initscr()
c = stdscr.getch()
print 'you entered', chr(c)
curses.endwin()

Curses.getch()は、キャストしたときと同じ出力になるように押されたキーの序数を返します。

13
John Gaines Jr.

クロスプラットフォーム、Python 2/3コード:

# import sys, os

def wait_key():
    ''' Wait for a key press on the console and return it. '''
    result = None
    if os.name == 'nt':
        import msvcrt
        result = msvcrt.getch()
    else:
        import termios
        fd = sys.stdin.fileno()

        oldterm = termios.tcgetattr(fd)
        newattr = termios.tcgetattr(fd)
        newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
        termios.tcsetattr(fd, termios.TCSANOW, newattr)

        try:
            result = sys.stdin.read(1)
        except IOError:
            pass
        finally:
            termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)

    return result

Fctl/non-blockingなものを削除したのは、それがIOErrorsを与えていたので必要ではなかったからです。ブロックしたいので、このコードを使用しています。 ;)

12
Gringo Suave

あなたがエンターを待ちたいのであれば(それでユーザーがキーボードをノックしても意図しない何かが起きることはありません)

sys.stdin.readline()
2
andrew pate

私はpythonが初めてなので、ここで行われた最も簡単な提案を再現するには愚かすぎると思っていました。結局のところ、知っておくべき落とし穴があります。

PythonスクリプトがIDLEから実行されると、いくつかのIOコマンドは(実際には端末ウィンドウがないので)まったく異なる動作をするようです。

例えば。 msvcrt.getchはノンブロッキングで、常に$ ffを返します。これはすでにずっと前に報告されています(例: https://bugs.python.org/issue9290 を参照) - 修正済みとしてマークされていますが、どういうわけか問題は現在のバージョンのpython/IDLEでも解決しないようです。

そのため、上記のコードのいずれかがうまくいかない場合は、手動でスクリプトを実行し、NOT IDLEからを試してください。

2
ralfiii

あなたが彼らが正確なキーを押したかどうかを見たいならば(例えば 'b'のように)これをしてください:

while True:
    choice = raw_input("> ")

    if choice == 'b' :
        print "You win"
        input("yay")
        break
1
E40

os.systemは常にshを呼び出すようですが、これは読み取り用のsおよびnオプションを認識しません。ただし、readコマンドはbashに渡すことができます。

 os.system("""bash -c 'read -s -n 1 -p "Press any key to continue..."'""")
0
James King