Czytam dane szeregowe i piszę do pliku csv za pomocą pętli while. Chcę, aby użytkownik mógł wyłączyć pętlę while, gdy poczuje, że zebrał wystarczającą ilość danych.
while True:
#do a bunch of serial stuff
#if the user presses the 'esc' or 'return' key:
break
Zrobiłem coś takiego za pomocą opencv, ale wygląda na to, że nie działa w tej aplikacji (i tak naprawdę nie chcę importować opencv tylko dla tej funkcji) ...
# Listen for ESC or ENTER key
c = cv.WaitKey(7) % 0x100
if c == 27 or c == 10:
break
Więc. Jak mogę pozwolić użytkownikowi wyrwać się z pętli?
Nie chcę też używać przerwania klawiatury, ponieważ skrypt musi nadal działać po zakończeniu pętli while.
python
while-loop
break
Chris
źródło
źródło
^C
jest wydawana podczasdo_something()
. Jak możesz tego uniknąć?do_something()
odczytuje pewne wartości z USB, więc jeśli^C
jest wydawane, gdy jestem w środkudo_something()
mam nieprzyjemnych błędów komunikacyjnych. Zamiast tego, jeśli jestem nawhile
zewnątrzdo_something()
, wszystko jest gładkie. Tak więc zastanawiałem się, jak sobie z tym poradzić. Nie jestem pewien, czy wyraziłem się wystarczająco jasno.pyVISA
i telefonmatplotlib
, aby mieć wizualizację moich pomiarów na żywo. I czasami dostaję dziwne błędy. Myślę, że powinienem otworzyć osobne pytanie i przestać zanieczyszczać twoją odpowiedź ...Istnieje rozwiązanie, które nie wymaga niestandardowych modułów i jest w 100% przenośne
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()
źródło
thread
->_thread
iraw_input
->input
. Musisz nacisnąć klawisz Enter, aby zasilić linię. Jeśli chcesz to zrobić na dowolnym klawiszu, użyj getch .następujący kod działa dla mnie. Wymaga openCV (import cv2).
Kod składa się z nieskończonej pętli, która nieustannie szuka naciśniętego klawisza. W tym przypadku naciśnięcie klawisza „q” powoduje zakończenie programu. Inne klawisze mogą być naciskane (w tym przykładzie „b” lub „k”), aby wykonać różne czynności, takie jak zmiana wartości zmiennej lub wykonanie funkcji.
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 ...
źródło
W przypadku Pythona 3.7 skopiowałem i zmieniłem bardzo ładną odpowiedź użytkownika297171, więc działa ona we wszystkich scenariuszach w Pythonie 3.7, które testowałem.
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()
źródło
pyHook może pomóc. http://sourceforge.net/apps/mediawiki/pyhook/index.php?title=PyHook_Tutorial#tocpyHook%5FTutorial4
Zobacz zaczepy klawiatury; jest to bardziej uogólnione - jeśli chcesz mieć określone interakcje z klawiaturą, a nie tylko używać funkcji KeyboardInterrupt.
Ponadto ogólnie (w zależności od zastosowania) myślę, że opcja Ctrl-C nadal dostępna do zabicia skryptu ma sens.
Zobacz też poprzednie pytanie: Wykryj w Pythonie, które klawisze są naciskane
źródło
Jest zawsze
sys.exit()
.Biblioteka systemowa w podstawowej bibliotece Pythona ma funkcję wyjścia, która jest bardzo przydatna podczas tworzenia prototypów. Kod byłby podobny do:
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()
źródło
raw_input
zastępuje sięinput
Zmodyfikowałem odpowiedź z rayzinnz, aby zakończyć skrypt określonym kluczem, w tym przypadku klawiszem 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()
źródło
Od podążania tym wątkiem w dół króliczej nory doszedłem do tego, działa na Win10 i Ubuntu 20.04. Chciałem czegoś więcej niż tylko zabicia skryptu i użycia określonych kluczy, a to musiało działać zarówno w MS, jak i Linuksie.
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()
źródło
Może to być pomocne podczas instalacji pynput z - 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
źródło
To jest rozwiązanie, które znalazłem z wątkami i standardowymi bibliotekami
Pętla działa do momentu naciśnięcia jednego klawisza
Zwraca klawisz wciśnięty jako pojedynczy ciąg znaków
Działa w Pythonie 2.7 i 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()
źródło
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(' :( ')
aby wejść użyj 'ENTER'
źródło