2012-08-29 21 views
33

Jestem nowy w Pythonie i właśnie stworzyłem grę i menu w Pythonie. Pytanie brzmi, że użycie (raw_) input() wymaga ode mnie wciśnięcia enter po każdym naciśnięciu klawisza, chciałbym, aby naciśnięcie strzałki w dół natychmiast zmieni następny element menu lub przesunie się w dół w grze. W tej chwili wymaga mi, aby mi się podoba typ "dół", a następnie naciśnij enter. Zrobiłem też sporo badań, ale wolałbym nie pobierać wielkich modułów (np. Pygame) tylko po to, aby osiągnąć pojedynczą metodę keyDown(). Czy są jakieś prostsze sposoby, których nie mogłem znaleźć?Metoda Pythona do czytania naciśnięcia klawisza?

Edit: Właśnie dowiedziałem się, że msvcrt.getch() by rade. To nie jest keyDown(), ale działa. Jednak nie jestem pewien, jak tego użyć, czy nie wydaje się dość dziwna, jakakolwiek pomoc tutaj? To jest to, co mam w tej chwili:

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

jednak utrzymuje dając mi te wszystkie bajty nonsens, na przykład strzałki w dół, jest to:

b'\xe0' 
b'P' 

I nie mam pojęcia, jak używaj ich, próbowałem porównać z chr(), a nawet użyć ord(), ale nie mogę zrobić żadnych porównań. To, co próbuję zrobić, to w zasadzie:

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

I tak dalej ... Jakakolwiek pomoc?

+0

Nie duplikat tego. Dotyczy to zdarzeń kluczowych, a nie wprowadzania pojedynczych znaków. – Deestan

+7

Mogę haz rozwiązanie cross-platform? 'msvcrt' nie jest dostępny na dystrybucjach mac/linux w Pythonie – cat

Odpowiedz

47

Zorientowałem się, testując wszystkie rzeczy sam. Nie można znaleźć żadnych tematów na ten temat, więc po prostu zostawię rozwiązanie tutaj. To nie może być jedyne lub nawet najlepsze rozwiązanie, ale działa na moje potrzeby (w granicach getcha) i jest lepsze niż nic.

Uwaga: prawidłowy keyDown(), który rozpoznałby wszystkie klawisze i faktyczne naciśnięcia przycisków, jest nadal wyceniany.

Rozwiązanie: użyciu ord() -function najpierw obrócić getch() do liczby całkowitej (chyba że są wirtualne kodów klawiszy, ale nie jestem pewien) działa prawidłowo, a następnie porównując wynik do rzeczywistej liczby reprezentującej chciał klawisz. Ponadto, gdybym potrzebował, mógłbym dodać dodatkową liczbę chr() wokół zwróconej liczby, aby przekształcić ją w znak. Jednak używam głównie strzałek w dół, esc itp., Więc przekształcenie ich w postać byłoby głupie.Oto ostateczny kod:

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() 

Także jeśli ktoś potrzebuje, można łatwo dowiedzieć się keycodes z Google, lub za pomocą python i po prostu naciskając klawisz:

from msvcrt import getch 
while True: 
    print(ord(getch())) 
+2

Dziękuję, to była pierwsza odpowiedź, która zadziałała dla mnie. +1 –

+1

Korzystam z powyższego kodu, ale mój kod po prostu blokuje przy funkcji getch(), a wtedy nic się nie dzieje. jakaś pomoc ? –

+1

@AnumSheraz Powyższa metoda działa tylko wtedy, gdy uruchamiasz kod z wiersza poleceń. – Moondra

8

Zobacz dokumentację MSDN getch. W szczególności:

Funkcje _getch and_getwch odczytują pojedynczy znak z konsoli bez echa znaku. Żadnej z tych funkcji nie można użyć do odczytu CTRL + C. Podczas czytania klawisza funkcyjnego lub klawisza strzałki każda funkcja musi być wywołana dwa razy; pierwsze wywołanie zwraca 0 lub 0xE0, a drugie wywołanie zwraca rzeczywisty kod klucza.

Funkcja Python zwraca znak. możesz użyć ord(), aby uzyskać wartość całkowitą, którą możesz przetestować, na przykład keycode = ord(msvcrt.getch()).

Jeśli więc czytasz 0x00 lub 0xE0, przeczytaj go po raz drugi, aby uzyskać kod klawisza dla strzałki lub klawisza funkcyjnego. Z eksperymentów, 0x00 poprzedza F1-F10 (0x3B-0x44), a 0xE0 poprzedza klawisze strzałek i Ins/Del/Home/End/PageUp/PageDown.

+0

Cóż, już to wymyśliłem, ale nie mogę opublikować ostatecznego rozwiązania. Ale ten + ord() + char() –

0
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() 
+2

Proszę dodać wyjaśnienie do swojej odpowiedzi, aby objaśnić swój kod. – AJ123

Powiązane problemy