키 스트로크로 잠시 루프를 죽이는 방법?
저는 시리얼 데이터를 읽고 while loop을 사용하여 csv 파일에 쓰고 있습니다.사용자가 충분한 데이터를 수집했다고 생각하면 while loop을 죽일 수 있기를 바랍니다.
while True:
#do a bunch of serial stuff
#if the user presses the 'esc' or 'return' key:
break
opencv를 사용하여 이와 같은 작업을 수행했지만 이 애플리케이션에서 작동하지 않는 것 같습니다(그리고 어쨌든 이 기능만을 위해 opencv를 가져오고 싶지 않습니다).
# Listen for ESC or ENTER key
c = cv.WaitKey(7) % 0x100
if c == 27 or c == 10:
break
그래서. 어떻게 하면 사용자가 루프에서 벗어나도록 할 수 있을까요?
또한 while 루프가 종료된 후에도 스크립트가 계속 실행되어야 하기 때문에 키보드 인터럽트를 사용하고 싶지 않습니다.
가장 쉬운 방법은 그냥 일상적인 것으로 방해하는 것입니다.Ctrl-C
SIGINT) (SIGINT)
try:
while True:
do_something()
except KeyboardInterrupt:
pass
Ctrl-C
들KeyboardInterrupt
키워야 할 거야, 그냥 고리 밖에서 잡고 그냥 무시해요.
비표준 모듈이 필요 없고 100% 운반이 가능한 솔루션이 있습니다.
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()
다음 코드가 저에게 적합합니다.openCV(import cv2)가 필요합니다.
이 코드는 계속해서 눌러진 키를 찾는 무한 루프로 구성되어 있습니다.이 경우 'q' 키를 누르면 프로그램이 종료됩니다.다른 키(이 예에서는 'b' 또는 'k')를 눌러 변수 값을 변경하거나 기능을 실행하는 등의 다양한 작업을 수행할 수 있습니다.
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 ...
Python 3.7의 경우 user297171의 아주 멋진 답변을 복사하고 변경하여 테스트한 Python 3.7의 모든 시나리오에서 작동합니다.
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()
pip install keyboard
import keyboard
while True:
# do something
if keyboard.is_pressed("q"):
print("q pressed, ending loop")
break
여기 저에게 효과가 있었던 해결책이 있습니다.여기저기 게시물에서 아이디어를 얻었습니다.정의된 키(abortKey)를 누를 때까지 루프가 종료되지 않습니다.루프는 가능한 한 빨리 중지되고 다음 반복으로 실행하려고 하지 않습니다.
from pynput import keyboard
from threading import Thread
from time import sleep
def on_press(key, abortKey='esc'):
try:
k = key.char # single-char keys
except:
k = key.name # other keys
print('pressed %s' % (k))
if k == abortKey:
print('end loop ...')
return False # stop listener
def loop_fun():
while True:
print('sleeping')
sleep(5)
if __name__ == '__main__':
abortKey = 't'
listener = keyboard.Listener(on_press=on_press, abortKey=abortKey)
listener.start() # start to listen on a separate thread
# start thread with loop
Thread(target=loop_fun, args=(), name='loop_fun', daemon=True).start()
listener.join() # wait for abortKey
파이훅이 도움이 될 겁니다http://sourceforge.net/apps/mediawiki/pyhook/index.php?title=PyHook_Tutorial#tocpyHook%5FTutorial4
키보드 후크 참조. 키보드만 사용하는 것이 아니라 특정 키보드 상호 작용을 원하는 경우 보다 일반화됩니다.방해하다.
또한 일반적으로 (사용 용도에 따라) Ctrl-C 옵션을 사용하여 스크립트를 삭제하는 것이 타당하다고 생각합니다.
이전 질문도 참조:python에서 어떤 키를 눌렀는지 탐지
ㅇㅇ가 .sys.exit()
.
파이썬의 핵심 라이브러리에 있는 시스템 라이브러리에는 프로토타입 제작 시 매우 편리한 exit 기능이 있습니다.코드는 다음과 같습니다.
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()
나는 rayzinnz의 답을 특정 키로 스크립트를 끝내도록 수정했습니다, 이 경우 탈출 키.
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()
라이브러리에서 입니다. 와 에서 입니다 은 입니다 에서 와
됩니다.
입력한 합니다.
2 및 3Python 2.7및 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()
이 스레드를 따라 토끼구멍을 내려가면서 저는 이것에 도달했고, Win10과 Ubuntu 20.04에서 작동합니다.저는 단순히 스크립트를 죽이는 것 이상의 것을 원했고, 특정 키를 사용하기를 원했고, MS와 리눅스 둘 다에서 작동해야 했습니다.
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()
로 인정된 답변.KeyboardInterrupt
저는 신뢰할 수 없었지만, pyinput으로 다음과 같은 솔루션이 가능했습니다(Python 3.10, Linux).While-loop은 다음과 같이 종료됩니다.q
를 누릅니다
from pynput.keyboard import Listener # pip install pynput
keyboard_quit = False
def keyboard_handler(key):
global keyboard_quit
if hasattr(key, 'char') and key.char == 'q':
keyboard_quit = True
keyboard_listener = Listener(on_press=keyboard_handler)
keyboard_listener.start() # Non-blocking
while not keyboard_quit:
# Do something
이것은 --pip install pynput을 사용한 설치 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
여기에 현재 반복을 안전하게 종료한 후 종료하는 간단한 Windows 솔루션이 있습니다.'Esc' 키로 루프를 깨고 종료하는 카운터 예제와 함께 사용했습니다.msvcrt 패키지의 kbhit() 및 getch() 기능을 사용합니다.타임 패키지는 이벤트 간에 시간 지연을 설정하기 위한 완화 이유로만 호출됩니다.
import msvcrt, time
print("Press 'Esc' to stop the loop...")
x = 0
while True:
x += 1
time.sleep(0.5)
print(x)
if msvcrt.kbhit():
if msvcrt.getch() == b'\x1b':
print("You have pressed Esc! See you!")
time.sleep(2)
break
kbhit() 함수는 키 누르기가 읽기 대기 중인 경우 True를 반환합니다.
getch() 함수는 키 누름을 읽고 결과 문자를 바이트 문자열로 반환합니다.어떤 키와 함께 사용해도 좋습니다.
b'\x1b'는 'Esc' 키의 바이트 문자열 문자입니다.
다음은 잡을 필요 없이 을 사용하는 또 다른 예입니다.SIGINT
(Ctrl+c
).
답변 했듯이 @Atcold 의 에서 처럼 한 를 된 를 처럼 Ctrl+c
루프에서 장시간 실행 작업을 중단하고 정의되지 않은 상태로 둘 수 있습니다.호출 중인 라이브러리에서 장시간 실행되는 작업이 발생하면 특히 짜증이 날 수 있습니다.
는 에서 는 가 를 가 를 에서 q
요를 누릅니다.Enter
바로 하려면 . 를 하려면 과 이 합니다 합니다 이 를 과 하려면 ._Getch()
이 대답에서
import time
from threading import Thread, Event
def read_input(q_entered_event):
c = input()
if c == "q":
print("User entered q")
q_entered_event.set()
def do_long_running_stuff():
q_pressed_event = Event()
input_thread = Thread(target=read_input,
daemon=True,
args=(q_pressed_event,))
input_thread.start()
while True:
print("I am working ...")
time.sleep(1)
if q_pressed_event.is_set():
break
print("Process stopped by user.")
if __name__ == "__main__":
do_long_running_stuff()
from time import sleep
from threading import Thread
import threading
stop_flag = 0
def Wait_Char():
global stop_flag
v = input("Enter Char")
if(v == "z"):
stop_flag = 1
def h():
while(True):
print("Hello Feto")
time.sleep(1)
if(stop_flag == 1):
break
thread1 = Thread(target=Wait_Char)
thread2 = Thread(target=h)
thread1.start()
thread2.start()
print("threads finished...exiting")
이것은 최선의 방법은 아니지만 당신이 원하는 일을 할 수 있습니다.
Running 2 Threads 한 개는 사용자가 루프를 중지할 키를 기다리고 있습니다.
방식Wait_Char 방식)
는 루프용개로개p한d
방법HΩ)
그리고 둘 다 정지 과정을 제어하는 전역 변수 stop_flag를 봅니다. z를 누르면 정지합니다.
from pynput import keyboard
def on_press(key):
if key == keyboard.Key.esc:
return False
i = 0
with keyboard.Listener(on_press=on_press) as listener:
# Your infinite loop
while listener.running:
print(i)
i=i+1
print("Done")
효과가 있습니다...
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(' :( ')
entry는 'ENTER'를 사용합니다.
언급URL : https://stackoverflow.com/questions/13180941/how-to-kill-a-while-loop-with-a-keystroke
'programing' 카테고리의 다른 글
폼 제어를 비활성화하되 값은 유지하는 방법 (0) | 2023.09.11 |
---|---|
원시 소켓을 특정 인터페이스에 바인딩하는 방법 (0) | 2023.09.11 |
워드프레스에서 댓글 ID에서 게시물 ID를 얻을 수 있습니까? (0) | 2023.09.11 |
libxml/tree.h 해당 파일 또는 디렉토리가 없습니다. (0) | 2023.09.11 |
PHP in_array()에서 키를 얻는 방법은 무엇입니까? (0) | 2023.09.11 |