108 votes

Comment tuer une boucle while en appuyant sur une touche ?

Je lis des données série et les écris dans un fichier csv en utilisant une boucle while. Je veux que l'utilisateur puisse arrêter la boucle while lorsqu'il estime avoir recueilli suffisamment de données.

while True:
    #do a bunch of serial stuff

    #if the user presses the 'esc' or 'return' key:
        break

J'ai fait quelque chose de semblable en utilisant opencv, mais cela ne semble pas fonctionner dans cette application (et je ne veux vraiment pas importer opencv juste pour cette fonction de toute façon)...

        # Listen for ESC or ENTER key
        c = cv.WaitKey(7) % 0x100
        if c == 27 or c == 10:
            break

Alors. Comment puis-je laisser l'utilisateur sortir de la boucle ?

De plus, je ne veux pas utiliser l'interruption du clavier, car le script doit continuer à s'exécuter après la fin de la boucle while.

169voto

Keith Points 13800

Le moyen le plus simple est de l'interrompre avec l'habituel Ctrl-C (SIGINT).

try:
    while True:
        do_something()
except KeyboardInterrupt:
    pass

Depuis Ctrl-C causes KeyboardInterrupt pour être soulevée, il suffit de l'attraper en dehors de la boucle et de l'ignorer.

44voto

Il existe une solution qui ne nécessite aucun module non standard et qui est 100 % transportable :

import _thread

def input_thread(a_list):
    raw_input()             # use input() in Python3
    a_list.append(True)

def do_stuff():
    a_list = []
    _thread.start_new_thread(input_thread, (a_list,))
    while not a_list:
        stuff()

16voto

Luis Jose Points 378

Le code suivant fonctionne pour moi. Il nécessite openCV (import cv2).

Le code est composé d'une boucle infinie qui recherche en permanence une touche enfoncée. Dans ce cas, lorsque la touche 'q' est enfoncée, le programme se termine. D'autres touches peuvent être pressées (dans cet exemple, 'b' ou 'k') pour effectuer différentes actions, comme changer la valeur d'une variable ou exécuter une fonction.

import cv2

while True:
    k = cv2.waitKey(1) & 0xFF
    # press 'q' to exit
    if k == ord('q'):
        break
    elif k == ord('b'):
        # change a variable / do something ...
    elif k == ord('k'):
        # change a variable / do something ...

11voto

rayzinnz Points 492

Pour Python 3.7, j'ai copié et modifié la très belle réponse de l'utilisateur 297171 afin qu'elle fonctionne dans tous les scénarios de Python 3.7 que j'ai testés.

import threading as th

keep_going = True
def key_capture_thread():
    global keep_going
    input()
    keep_going = False

def do_stuff():
    th.Thread(target=key_capture_thread, args=(), name='key_capture_thread', daemon=True).start()
    while keep_going:
        print('still going...')

do_stuff()

7voto

user15083300 Points 71
pip install keyboard

import keyboard

while True:
    # do something
    if keyboard.is_pressed("q"):
        print("q pressed, ending loop")
        break

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X