45

私はPythonを初めて使用し、Pythonでゲームとメニューを作成しました。質問は、(raw_)input()を使用するには、キーを押すたびにEnterキーを押す必要があるということです。下矢印を押すと、すぐに次のメニュー項目が選択されるか、ゲーム内で下に移動するようにしたいと思います。現時点では、「down」と入力してEnterキーを押す必要があります。私もかなり多くの調査を行いましたが、単一のkeyDown()メソッドを実現するためだけに、巨大なモジュール(pygameなど)をダウンロードしたくありません。それで、私が見つけられなかったもっと簡単な方法はありますか?

編集:msvcrt.getch()それがトリックを行う ことがわかった。keyDown()ではありませんが、機能します。しかし、私もそれを使用する方法がわかりません、それはかなり奇妙に思えます、ここで何か助けはありますか?これは私が現時点で得たものです:

from msvcrt import getch
while True:
    key = getch()
    print(key)

しかし、それは私にこれらすべてのナンセンスバイトを与え続けます、例えば、下矢印はこれです:

b'\xe0'
b'P'

そして、それらの使い方がわかりません。chr()と比較したり、ord()を使用したりしましたが、実際には比較できません。私がやろうとしていることは基本的にこれです:

from msvcrt import getch
while True:
    key = getch()
    if key == escape:
        break
    elif key == downarrow:
        movedown()
    elif key == 'a':
        ...

など...何か助けはありますか?

4

7 に答える 7

63

自分ですべてのものをテストすることによってそれを理解しました。それに関するトピックが見つからなかったので、ここで解決策を残しておきます。これが唯一の、あるいは最良の解決策ではないかもしれませんが、それは私の目的(ゲッチの制限内)で機能し、何もないよりはましです。

注:keyDown()すべてのキーと実際のキーの押下を認識する適切な値は、引き続き評価されます。

解決策:ord() -functionを使用して、最初にgetch()を整数に変換し(仮想キーコードだと思いますが、あまり確実ではありません)、結果を必要なキーを表す実際の数値と比較します。また、必要に応じて、chr()返された数値の前後に余分な文字を追加して、文字に変換することもできます。ただし、私は主に下矢印やescなどを使用しているので、それらを文字に変換するのはばかげています。最終的なコードは次のとおりです。

from msvcrt import getch
while True:
    key = ord(getch())
    if key == 27: #ESC
        break
    elif key == 13: #Enter
        select()
    elif key == 224: #Special keys (arrows, f keys, ins, del, etc.)
        key = ord(getch())
        if key == 80: #Down arrow
            moveDown()
        elif key == 72: #Up arrow
            moveUp()

また、他の誰かが必要な場合は、グーグルから、またはPythonを使用してキーを押すだけで、キーコードを簡単に見つけることができます。

from msvcrt import getch
while True:
    print(ord(getch()))
于 2012-08-29T14:01:26.187 に答える
10

MSDNのgetchドキュメントを参照してください。具体的には:

_getchおよび_getwch関数は、文字をエコーせずにコンソールから単一の文字を読み取ります。これらの関数はいずれも、CTRL+Cの読み取りには使用できません。ファンクションキーまたは矢印キーを読み取るときは、各関数を2回呼び出す必要があります。最初の呼び出しは0または0xE0を返し、2番目の呼び出しは実際のキーコードを返します。

Python関数は文字を返します。ord()たとえば、テストできる整数値を取得するために使用できますkeycode = ord(msvcrt.getch())

したがって、0x00または0xE0を読み取る場合は、もう一度読んで、矢印またはファンクションキーのキーコードを取得してください。実験から、0x00はF1-F10(0x3B-0x44)の前にあり、0xE0は矢印キーとIns / Del / Home / End / PageUp/PageDownの前にあります。

于 2012-08-29T12:45:42.417 に答える
4

すべての回答と元の質問にコメントする必要があるため、これをコメントとして投稿したくありませんでした。

すべての答えは、MSVCRT MicrosoftVisualCランタイムに依存しているようです。その依存関係を避けたい場合:

クロスプラットフォームのサポートが必要な場合は、次のライブラリを使用してください。

https://pypi.org/project/getkey/#files

https://github.com/kcsaff/getkey

よりエレガントなソリューションを可能にします。

コード例:

from getkey import getkey, keys
key = getkey()
if key == keys.UP:
  ...  # Handle the UP key
elif key == keys.DOWN:
  ...  # Handle the DOWN key
elif key == 'a':
  ...  # Handle the `a` key
elif key == 'Y':
  ...  # Handle `shift-y`
else:
  # Handle other text characters
  buffer += key
  print(buffer)
于 2019-08-17T08:12:29.443 に答える
1
from msvcrt import getch

pos = [0, 0]

def fright():
    global pos
    pos[0] += 1

def fleft():
    global pos 
    pos[0] -= 1

def fup():
    global pos
    pos[1] += 1

def fdown():
    global pos
    pos[1] -= 1

while True:
    print'Distance from zero: ', pos
    key = ord(getch())
    if key == 27: #ESC
        break
    elif key == 13: #Enter
        print('selected')
    elif key == 32: #Space
        print('jump')
    elif key == 224: #Special keys (arrows, f keys, ins, del, etc.)
        key = ord(getch())
        if key == 80: #Down arrow
            print('down')
            fdown
        elif key == 72: #Up arrow
            print('up')
            fup()
        elif key == 75: #Left arrow
            print('left')
            fleft()
        elif key == 77: #Right arrow
            print('right')
            fright()
于 2017-05-15T19:32:20.983 に答える
1

私もこれを達成しようとしていました。上記のコードから、私が理解したのは、関数から両方のバイトを取得するために、getch()関数を複数回呼び出すことができるということでした。したがって、バイトオブジェクトでの使用を検討しているだけの場合は、ord()関数は必要ありません。

while True :
    if m.kbhit() :
        k = m.getch()
        if b'\r' == k :
            break
        elif k == b'\x08'or k == b'\x1b':
            # b'\x08' => BACKSPACE
            # b'\x1b' => ESC
            pass
        elif k == b'\xe0' or k == b'\x00':
            k = m.getch()
            if k in [b'H',b'M',b'K',b'P',b'S',b'\x08']:
                # b'H' => UP ARROW
                # b'M' => RIGHT ARROW
                # b'K' => LEFT ARROW
                # b'P' => DOWN ARROW
                # b'S' => DELETE
                pass
            else:
                print(k.decode(),end='')
        else:
            print(k.decode(),end='')

このコードは、CMDまたはIDEでEnterキーが押されるまで任意のキーを印刷します(私はVS CODEを使用していました)必要に応じて、特定のキーのif内でカスタマイズできます

于 2020-05-02T13:23:38.330 に答える
1

今は本当に遅いですが、各コマンドラインを使用するだけで、Windows、Mac、Linuxで動作する簡単なスクリプトを作成しました。

import os, platform

def close():
    if platform.system() == "Windows":
        print("Press any key to exit . . .")
        os.system("pause>nul")
        exit()
    
    elif platform.system() == "Linux":
        os.system("read -n1 -r -p \"Press any key to exit . . .\" key")
        exit()
    
    elif platform.system() == "Darwin":
        print("Press any key to exit . . .")
        os.system("read -n 1 -s -p \"\"")
        exit()
    
    else:
        exit()

組み込み関数のみを使用し、3つすべてで機能するはずです(ただし、WindowsとLinuxのみをテストしました...)。

于 2021-01-27T10:30:03.727 に答える
0
import keyboard

def mywait():
    keyboard.read_key()

def my_function():
    print("going down")

def my_exit():
    quit()

keyboard.add_hotkey('down', my_function)
keyboard.add_hotkey('esc', my_exit)

while True:
    mywait()
于 2021-12-08T10:39:44.013 に答える