Estou lendo dados seriais e gravando em um arquivo csv usando um loop while. Desejo que o usuário seja capaz de eliminar o loop while assim que sentir que coletou dados suficientes.
while True:
#do a bunch of serial stuff
#if the user presses the 'esc' or 'return' key:
break
Eu fiz algo assim usando o opencv, mas não parece estar funcionando neste aplicativo (e eu realmente não quero importar o opencv apenas para esta função de qualquer maneira) ...
# Listen for ESC or ENTER key
c = cv.WaitKey(7) % 0x100
if c == 27 or c == 10:
break
Então. Como posso deixar o usuário sair do loop?
Além disso, não quero usar a interrupção do teclado, porque o script precisa continuar a ser executado após o loop while terminar.
python
while-loop
break
Chris
fonte
fonte
^C
é emitido enquanto emdo_something()
. Como voce pode evitar isso?do_something()
lê alguns valores do USB, portanto, se^C
for emitido enquanto estou dentrodo_something()
, recebo erros de comunicação desagradáveis. Em vez disso, se estou dentrowhile
, fora dodo_something()
, tudo está tranquilo. Então, eu queria saber como lidar com essa situação. Não tenho certeza se fui claro o suficiente.pyVISA
e uma chamada paramatplotlib
, para que possa ter uma visualização ao vivo das minhas medições. E às vezes recebo erros funky. Acho que devo abrir uma pergunta separada e parar de poluir a sua resposta ...Existe uma solução que não requer módulos fora do padrão e é 100% transportável
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()
fonte
thread
->_thread
eraw_input
->input
. Você tem que pressionar enter para alimentar a linha. Se você quiser fazer em qualquer tecla, use getch .o código a seguir funciona para mim. Requer openCV (import cv2).
O código é composto por um loop infinito que está continuamente procurando uma tecla pressionada. Neste caso, quando a tecla 'q' é pressionada, o programa termina. Outras teclas podem ser pressionadas (neste exemplo 'b' ou 'k') para realizar ações diferentes, como alterar um valor de variável ou executar uma função.
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 ...
fonte
Para Python 3.7, copiei e alterei a ótima resposta do usuário 297171 para que funcione em todos os cenários do Python 3.7 que testei.
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()
fonte
pyHook pode ajudar. http://sourceforge.net/apps/mediawiki/pyhook/index.php?title=PyHook_Tutorial#tocpyHook%5FTutorial4
Veja os ganchos do teclado; isso é mais generalizado - se você deseja interações específicas do teclado e não apenas usando KeyboardInterrupt.
Além disso, em geral (dependendo do seu uso), acho que faz sentido ter a opção Ctrl-C ainda disponível para matar seu script.
Veja também a pergunta anterior: Detectar em python quais teclas são pressionadas
fonte
Sempre existe
sys.exit()
.A biblioteca do sistema na biblioteca central do Python tem uma função de saída que é muito útil durante a prototipagem. O código seria mais ou menos:
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()
fonte
raw_input
é substituído porinput
Modifiquei a resposta de rayzinnz para terminar o script com uma chave específica, neste caso a tecla 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()
fonte
Seguindo este tópico pela toca do coelho, cheguei a isso, funciona no Win10 e no Ubuntu 20.04. Eu queria mais do que apenas matar o script e usar chaves específicas, e ele tinha que funcionar tanto no MS quanto no 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()
fonte
Isso pode ser útil instalar pynput com - 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
fonte
Esta é a solução que encontrei com threads e bibliotecas padrão O
Loop continua até que uma tecla seja pressionada
Retorna a tecla pressionada como uma única string de caracteres
Funciona no Python 2.7 e 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()
fonte
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 entrar use 'ENTER'
fonte