in un programma lanciato da riga di comando, senza bottoni o oggetti grafici, volevo che fosse consentito premere un pulsante per terminare un loop ma che però, se non viene premuto nulla, il loop resti in esecuzione.
In pratica l'operatore deve poter fermare un programma, tramite la pressione di un tasto, ma il programma dovrebbe continuare a essere in esecuzione: se non si preme nessun tasto il loop prosegue.
Ho cercato varie soluzioni, alcuni proponevano di usare la tecnica dei thread, altri funzioni complicate o la pressione del CTRL+C o break che però interrompono il programma immediatamente.
Alla fine la soluzione trovata è con la funzione getche() e con un timeout, trascorso il quale, il programma prosegue l'esecuzione del loop.
Il programma di esempio mostra a video il progressivo di numeri con a fianco la somma di tutti i precedenti, se l'operatore preme il tasto S il programma si ferma e mostra la somma finale.
Nell'esempio il loop, se non interrotto, si ferma dopo 50 numeri con un tempo di attesa di 0,2 secondi.
#----------------------------------------------------------------------+
# Programma : press_key versione 1.01 del 10/02/2017 |
# Python versione : 3.6.0 |
#----------------------------------------------------------------------+
#-----------------------------------------
# Import moduli
#-----------------------------------------
import sys, time, msvcrt
#---- Definizione variabili globali - Costanti fisse ------
DEBUG = 0
DELAY = 0.2 # tempo attesa per consentire di premere tasto S per STOP
MAX_NUM = 51 # Numero massimo
#------------------------------------------------------------------------------
# readInput : Attende la pressione di un tasto per un tempo max = timeout
#------------------------------------------------------------------------------
# input : Scritta da stampare, default (vuoto), timeout
# return: carattere premuto
#------------------------------------------------------------------------------
def readInput( caption, default, timeout):
start_time = time.time()
if caption > "":
print(caption)
sys.stdout.flush()
input = ''
while True:
if msvcrt.kbhit():
byte_arr = msvcrt.getche()
input = str.lower(byte_arr.decode('utf-8'))
return input
break
if len(input) == 0 and (time.time() - start_time) > timeout:
break
if len(input) > 0:
return input
else:
return default
#------------------------------------------------------------------------------
# INIZIO PROGRAMMA
#------------------------------------------------------------------------------
if __name__=='__main__':
somma = 0
i = 0
print ("Premi S per fermare >>")
for i in range(1, MAX_NUM):
somma = somma + i
print(("Numero = %3d"% (i)), "Somma = ", somma)
a = readInput("", "", DELAY)
if a == 's':
print ("\npremuto s")
print ("\nLa somma dei primi ", i, " numeri è ", somma)
break
elif a != '':
print ("") # per separare la riga con il carattere premuto
Nota: il programma funziona da riga di comando ma, se eseguito in ambiente IDLE, non intercetta i caratteri.
Nessun commento:
Posta un commento