[Python] Pygame: controllo della tastiera, senza interrompere il flusso.
Gabriele Battaglia
iz4apu a libero.it
Mar 7 Nov 2017 15:06:55 CET
Buongiorno.
Ho la necessità di leggere linput da tastiera senza che il flusso del
programma venga interrotto.
Non voglio utilizzare i threads.
Sto provando la libreria pygame che dovrebbe farlo ma...
Dopo averla importata, se scrivo:
>>> a=pygame.key.get_pressed()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
pygame.error: video system not initialized
>>>
E se inizializzo il video, non ho più la possibilità di scrivere del
testo sul terminale, con print.
Come potrei risolvere?
Per completezza, anche grazie a voi della lista, mi ero scritto il
modulo che riporto di seguito, per la gestione della tastiera, senza
interrompere il flusso del programma.
Il problema è che in Python 2 funziona bene, ma non va in Python 3, e
non da errori, quindi non capisco come posso convertirla da 2 a 3.
Grazie per gli spunti.
***
key.py
# -*- Coding: UTF8 -*-
from __future__ import print_function
# Utility di lettura tastiera 12/01/2015
# Grazie agli amici della lista Python.
# Versione 3.2.1 del 30/07/2016
# La funzione key
# Attende per il numero di secondi specificati
# se tempo e' scaduto, o si preme un tasto, esce.
# msg e' il messaggio da mostrare.
# Restituisce il tasto premuto. '''
# La funzione dgt
# tipo (str int float), min e max sono i limiti numerici o di lunghezza str
# dec il massimo numero di decimali, ritorna il valore immesso.
# Selezione sistema operativo
import sys
if sys.platform[:3].lower() == "dar":
# Mac
import termios, fcntl, os, time
def key(attesa=99999, msg=""):
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:
if msg != "": print (msg, end="")
t = time.time(); a = ""
while (time.time() - t <= attesa):
try:
c = sys.stdin.read(1)
time.sleep(0.025)
return c
except IOError: pass
return ""
finally:
termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)
elif sys.platform[:3].lower() == "win":
# Windows
import msvcrt, time
def key(attesa=99999, msg=""):
if msg != "": print (msg, end="")
t = time.time(); a = ""
while (time.time() - t <= attesa):
if msvcrt.kbhit(): a = msvcrt.getch()
if a != "": break
time.sleep(0.025)
return a
else:
print ("\nSistema operativo non supportato:\n\tContattare Gabriele
Battaglia.")
def dgt(tipo="s", msg="", min=-999999999999, max=999999999999, dec=2):
'''tipo = s, i, f, min max sono limiti numerici o lunghezza
stringa, mentre
dec e' il numero di decimali da tornare in caso di float, msg e' il
prompt.'''
import string
lmin = len(str(min))
if tipo == "s":
permesse = string.ascii_lowercase + string.ascii_uppercase +
string.digits + string.punctuation + " "
elif tipo == "f":
permesse = string.digits + "-,."
min, max = float(min), float(max)
elif tipo == "i":
permesse = string.digits + "-"
else:
print("DGT: chiamata con tipo non valido: ", type(tipo))
return
r = ""
if msg != "": print(msg, end = "")
while True:
s = key()
if tipo == "s":
if s == "\r" or s == "\n": return r
if s in permesse:
print(s, end="")
r += s
if len(r) > 0 and (s == "\x08" or s == "\x7f"): r = r[:-1];
print (s+" "+s,end="")
if len(r) == max: return r
elif tipo == "i":
if s == "\n" or s == "\r":
if r == "" or r == "-":
if min > 0: return int(min)
elif max < 0: return int(max)
else: return 0
if min > int(r): return int(min)
elif max < int(r): return int(max)
else: return int(r)
if s in permesse:
print(s, end="")
r += s
if len(r) == 1: permesse = string.digits
if r != "-":
tr = int(r)
if len(r) >= lmin and tr < min:
tr = min
return tr
elif tr > max:
tr = max
return tr
if len(r) > 0 and (s == "\x7f" or s == "\x08"): r = r[:-1];
print (s+" "+s,end="")
elif tipo == "f":
if s == "\r" or s == "\n":
if r == "" or r == "-" or r == ".":
if min > 0: return float(min)
elif max < 0: return float(max)
else: return 0.0
if min > float(r): return float(min)
elif max < float(r): return float(max)
else: return float(r)
if s in permesse:
print(s, end="")
r += s
if len(r) == 1: permesse = string.digits + ",."
if s == "." or s == ",":
if s == ",": r = r[:-1] + "."
if len(r) == 2 and r[0] == "-": r = "-0."
if len(r) == 1: r = "0."
k = 0
while k < dec:
s = key()
if s == "\r" or s == "\n":
if r[-1] == ".": r += "0"
return float(r)
if s in string.digits:
print(s, end="")
r += s
k += 1
tr = float(r)
if len(r) >= lmin and tr < min:
tr = min
return tr
elif tr > max:
tr = max
return tr
if k == dec: return float(r)
if r != "-":
tr = float(r)
if len(r) >= lmin and tr < min:
tr = min
return tr
elif tr > max:
tr = max
return tr
if len(r) > 0 and (s == "\x7f" or s == "\x08"): r = r[:-1];
print (s+" "+s,end="")
return
Maggiori informazioni sulla lista
Python