web-dev-qa-db-fra.com

Comment tuer une boucle while avec une frappe?

Je suis en train de lire des données série et d’écrire dans un fichier csv à l’aide d’une boucle while. Je souhaite que l'utilisateur puisse supprimer la boucle while une fois qu'il a collecté 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 comme ça en utilisant opencv, mais cela ne semble pas fonctionner dans cette application (et je ne veux vraiment pas importer d'opencv uniquement 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 d'interruption clavier, car le script doit continuer à s'exécuter après la fin de la boucle while.

59
Chris

Le moyen le plus simple consiste simplement à l’interrompre avec le Ctrl-C (SIGINT) habituel. 

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

Puisque Ctrl-C provoque la levée de KeyboardInterrupt, attrapez-le simplement en dehors de la boucle et ignorez-le.

108
Keith

Il existe une solution ne nécessitant aucun module non standard et pouvant être transportée à 100%

import thread

def input_thread(a_list):
    raw_input()
    a_list.append(True)

def do_stuff():
    a_list = []
    thread.start_new_thread(input_thread, (a_list,))
    while not a_list:
        stuff()
26
Barafu Albino

le code suivant fonctionne pour moi. Cela nécessite openCV (import cv2). 

Le code est composé d'une boucle infinie à la recherche continue d'une touche. Dans ce cas, lorsque vous appuyez sur la touche 'q', le programme se termine. Vous pouvez appuyer sur d'autres touches (dans cet exemple, «b» ou «k») pour effectuer différentes actions telles que modifier une valeur de 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 ...
9
Luis Jose

pyHook pourrait aider. http://sourceforge.net/apps/mediawiki/pyhook/index.php?title=PyHook_Tutorial#tocpyHook%5FTutorial4

Voir les crochets du clavier; ceci est plus généralisé - si vous voulez des interactions de clavier spécifiques et pas seulement l'utilisation de KeyboardInterrupt. 

En outre, en général (en fonction de votre utilisation), je pense qu’il est logique d’avoir l’option Ctrl-C toujours disponible pour tuer votre script. 

Voir aussi la question précédente: Détecter en python les touches enfoncées

4
Anov

Pour Python 3.7, j'ai copié et modifié la réponse très agréable de user297171, de sorte que cela fonctionne dans tous les scénarios que j'ai testés dans Python 3.7.

import _thread as thread

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

def do_stuff():
    thread.start_new_thread(key_capture_thread, ())
    while keep_going:
        print('still going...')

do_stuff()
2
rayzinnz

Cela peut être utile pour installer pynput avec - pip install pynput

from pynput.keyboard import Key, Listener
def on_release(key):
    if key == Key.esc:
        # Stop listener
        return False

# Collect events until released
while True:
    with Listener(
            on_release=on_release) as listener:
        listener.join()
    break 
0
ANKIT YADAV

Il y a toujours sys.exit().

La bibliothèque système de la bibliothèque principale de Python a une fonction de sortie qui est extrêmement pratique lors du prototypage . Le code ressemblerait à ceci:

import sys

while True:
    selection = raw_input("U: Create User\nQ: Quit")
    if selection is "Q" or selection is "q":
        print("Quitting")
        sys.exit()
    if selection is "U" or selection is "u":
        print("User")
        #do_something()
0
Julian Wise