Estoy leyendo datos en serie y escribiendo en un archivo csv usando un bucle while. Quiero que el usuario pueda eliminar el ciclo while una vez que sienta que ha recopilado suficientes datos.
while True:
#do a bunch of serial stuff
#if the user presses the 'esc' or 'return' key:
break
He hecho algo como esto usando opencv, pero parece que no funciona en esta aplicación (y de todos modos no quiero importar opencv solo para esta función) ...
# Listen for ESC or ENTER key
c = cv.WaitKey(7) % 0x100
if c == 27 or c == 10:
break
Entonces. ¿Cómo puedo dejar que el usuario se salga del círculo?
Además, no quiero usar la interrupción del teclado, porque el script debe continuar ejecutándose después de que finalice el ciclo while.
python
while-loop
break
Chris
fuente
fuente
^C
se emite mientras está endo_something()
. ¿Cómo se puede evitar esto?do_something()
lee algunos valores del USB, así que, si^C
se emite mientras estoy adentrodo_something()
, obtengo desagradables errores de comunicación. En cambio, si estoy en elwhile
, fuera deldo_something()
, todo está bien. Entonces, me preguntaba cómo manejar esta situación. No estoy seguro de haberme aclarado lo suficiente.pyVISA
y una llamada paramatplotlib
poder tener una visualización en vivo de mis medidas. Y a veces tengo errores raros. Creo que debería abrir una pregunta separada y dejar de contaminar tu respuesta ...Existe una solución que no requiere módulos no estándar y es 100% transportable
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()
fuente
thread
->_thread
yraw_input
->input
. Tienes que presionar enter para alimentar la línea. Si quieres hacerlo con cualquier tecla, usa getch .el siguiente código funciona para mí. Requiere openCV (importar cv2).
El código está compuesto por un bucle infinito que busca continuamente una tecla presionada. En este caso, cuando se presiona la tecla 'q', el programa finaliza. Se pueden presionar otras teclas (en este ejemplo, 'b' o 'k') para realizar diferentes acciones, como cambiar el valor de una variable o ejecutar una función.
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 ...
fuente
Para Python 3.7, copié y cambié la muy buena respuesta por user297171 para que funcione en todos los escenarios en Python 3.7 que probé.
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()
fuente
pyHook podría ayudar. http://sourceforge.net/apps/mediawiki/pyhook/index.php?title=PyHook_Tutorial#tocpyHook%5FTutorial4
Ver ganchos de teclado; esto es más generalizado, si desea interacciones de teclado específicas y no solo usar KeyboardInterrupt.
Además, en general (dependiendo de su uso), creo que tener la opción Ctrl-C todavía disponible para eliminar su script tiene sentido.
Ver también la pregunta anterior: Detectar en Python qué teclas están presionadas
fuente
Siempre la hay
sys.exit()
.La biblioteca del sistema en la biblioteca central de Python tiene una función de salida que es muy útil cuando se crean prototipos. El código estaría en la línea de:
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()
fuente
raw_input
se reemplaza porinput
Modifiqué la respuesta de rayzinnz para finalizar el script con una clave específica, en este caso la clave de escape
import threading as th import time import keyboard keep_going = True def key_capture_thread(): global keep_going a = keyboard.read_key() if a== "esc": keep_going = False def do_stuff(): th.Thread(target=key_capture_thread, args=(), name='key_capture_thread', daemon=True).start() i=0 while keep_going: print('still going...') time.sleep(1) i=i+1 print (i) print ("Schleife beendet") do_stuff()
fuente
Después de seguir este hilo por la madriguera del conejo, llegué a esto, funciona en Win10 y Ubuntu 20.04. Quería algo más que matar el script y usar claves específicas, y tenía que funcionar tanto en MS como en Linux ...
import _thread import time import sys import os class _Getch: """Gets a single character from standard input. Does not echo to the screen.""" def __init__(self): try: self.impl = _GetchWindows() except ImportError: self.impl = _GetchUnix() def __call__(self): return self.impl() class _GetchUnix: def __init__(self): import tty, sys def __call__(self): import sys, tty, termios fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) try: tty.setraw(sys.stdin.fileno()) ch = sys.stdin.read(1) finally: termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) return ch class _GetchWindows: def __init__(self): import msvcrt def __call__(self): import msvcrt msvcrt_char = msvcrt.getch() return msvcrt_char.decode("utf-8") def input_thread(key_press_list): char = 'x' while char != 'q': #dont keep doing this after trying to quit, or 'stty sane' wont work time.sleep(0.05) getch = _Getch() char = getch.impl() pprint("getch: "+ str(char)) key_press_list.append(char) def quitScript(): pprint("QUITTING...") time.sleep(0.2) #wait for the thread to die os.system('stty sane') sys.exit() def pprint(string_to_print): #terminal is in raw mode so we need to append \r\n print(string_to_print, end="\r\n") def main(): key_press_list = [] _thread.start_new_thread(input_thread, (key_press_list,)) while True: #do your things here pprint("tick") time.sleep(0.5) if key_press_list == ['q']: key_press_list.clear() quitScript() elif key_press_list == ['j']: key_press_list.clear() pprint("knock knock..") elif key_press_list: key_press_list.clear() main()
fuente
Esto puede ser útil para instalar pynput con - 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
fuente
Esta es la solución que encontré con subprocesos y bibliotecas estándar El
bucle continúa hasta que se presiona una tecla
Devuelve la tecla presionada como una cadena de un solo carácter
Funciona en Python 2.7 y 3
import thread import sys def getch(): import termios import sys, tty def _getch(): fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) try: tty.setraw(fd) ch = sys.stdin.read(1) finally: termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) return ch return _getch() def input_thread(char): char.append(getch()) def do_stuff(): char = [] thread.start_new_thread(input_thread, (char,)) i = 0 while not char : i += 1 print "i = " + str(i) + " char : " + str(char[0]) do_stuff()
fuente
import keyboard while True: print('please say yes') if keyboard.is_pressed('y'): break print('i got u :) ') print('i was trying to write you are a idiot ') print(' :( ')
para ingresar use 'ENTER'
fuente