Menggunakan curtsies modul ringan yang bagus, Anda dapat melakukan sesuatu seperti ini (diambil dari contoh/direktori mereka):
from curtsies import Input
def main():
with Input(keynames='curses') as input_generator:
for e in input_generator:
print(repr(e))
if __name__ == '__main__':
main()
Jadi, menekan tombol pada keyboard memberi Anda sesuatu seperti ini:
'a'
's'
'KEY_F(1)'
'KEY_F(2)'
'KEY_F(3)'
'KEY_F(4)'
'KEY_F(5)'
'KEY_LEFT'
'KEY_DOWN'
'KEY_UP'
'KEY_RIGHT'
'KEY_NPAGE'
'\n'
curtsies digunakan oleh bpython sebagai abstraksi tingkat rendah dari hal-hal yang berhubungan dengan terminal.
Masalah dasar decoding input adalah bahwa di berbagai terminal dan program emulator terminal seperti xterm
atau gnome-terminals
kunci yang sama secara fisik menghasilkan urutan kode kunci yang berbeda. Itu sebabnya seseorang perlu mengetahui pengaturan terminal mana yang harus digunakan untuk mendekode input. Modul semacam itu membantu mengabstraksi dari detail mengerikan itu.
Ini adalah loop sederhana yang akan membuat stdin dalam mode mentah (menonaktifkan buffering sehingga Anda tidak perlu menekan enter) untuk mendapatkan satu karakter. Anda harus melakukan sesuatu yang lebih cerdas (seperti with
pernyataan untuk menonaktifkannya) tetapi Anda mendapatkan idenya di sini:
import tty
import sys
import termios
orig_settings = termios.tcgetattr(sys.stdin)
tty.setcbreak(sys.stdin)
x = 0
while x != chr(27): # ESC
x=sys.stdin.read(1)[0]
print("You pressed", x)
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, orig_settings)
Saya pikir Anda harus mengulang untuk mendeteksi rilis kunci dengan Python.
ETA beberapa penjelasan lagi:
Di Linux, input ke program Anda akan buffer baris . Ini berarti bahwa sistem operasi akan menyangga input hingga memiliki seluruh baris, sehingga program Anda bahkan tidak akan melihat apa pun yang diketik pengguna hingga pengguna juga menekan 'enter'. Dengan kata lain, jika program Anda mengharapkan pengguna untuk mengetik 'w' dan pengguna melakukan ini, 'w' akan duduk di buffer OS sampai pengguna menekan 'enter'. Pada titik ini seluruh baris dikirimkan ke program Anda sehingga Anda akan mendapatkan string "w\n" sebagai masukan pengguna.
Anda dapat menonaktifkan ini dengan meletakkan tty dalam mode mentah . Anda melakukan ini dengan fungsi Python tty.setcbreak
yang akan memanggil driver tty di linux untuk memerintahkannya menghentikan buffering. Saya memberikannya sys.stdin
argumen untuk memberi tahu aliran mana yang ingin saya matikan untuk buffering. Jadi setelah tty.setcbreak
panggilan, loop di atas akan memberi Anda output untuk setiap tombol yang ditekan pengguna.
Namun, komplikasinya adalah setelah program Anda keluar, tty masih dalam mode mentah. Biasanya Anda akan menganggap ini tidak memuaskan karena Anda tidak mendapatkan daya apa pun yang ditawarkan oleh pengaturan terminal modern (seperti saat Anda menggunakan urutan kontrol atau escape). Misalnya, perhatikan bahwa Anda mungkin kesulitan keluar dari program dengan ctrl-C
. Oleh karena itu, Anda harus mengembalikan terminal ke mode matang setelah Anda selesai membaca karakter masukan. termios.tcsetattr
call hanya mengatakan "kembalikan terminal seperti yang saya temukan". Ia mengetahui cara melakukannya dengan terlebih dahulu memanggil termios.tcgetattr
di awal program yang mengatakan "beri tahu saya semua pengaturan terminal saat ini".
Setelah Anda memahami semua itu, Anda seharusnya dapat dengan mudah mengenkapsulasi fungsionalitas dalam fungsi yang sesuai dengan program Anda.
stdin
adalah aliran input yang datang kepada Anda dari pengguna. Wikipedia dapat memberi tahu Anda lebih banyak tentang streaming standar.