Как убить цикл while нажатием клавиши?

Я читаю последовательные данные и записываю их в файл csv, используя цикл while. Я хочу, чтобы пользователь мог убить цикл while, если почувствовал, что собрал достаточно данных.

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

Итак. Как я могу позволить пользователю вырваться из цикла?

Кроме того, я не хочу использовать прерывание клавиатуры, потому что script должен продолжать работать после завершения цикла while.

Ответ 1

Самый простой способ - просто прервать его с помощью обычного Ctrl-C (SIGINT).

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

Так как Ctrl-C вызывает повышение KeyboardInterrupt, просто поймайте его вне цикла и проигнорируйте его.

Ответ 2

Существует решение, которое не требует нестандартных модулей и на 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()

Ответ 3

для меня работает следующий код. Для этого требуется 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 ...

Ответ 4

pyHook может помочь. http://sourceforge.net/apps/mediawiki/pyhook/index.php?title=PyHook_Tutorial#tocpyHook%5FTutorial4

Смотрите клавиатурные крючки; это более обобщенно - если вам нужны определенные взаимодействия с клавиатурой, а не только с помощью KeyboardInterrupt.

Кроме того, в целом (в зависимости от вашего использования), я думаю, что наличие опции Ctrl-C, доступной для уничтожения вашего script, имеет смысл.

См. также предыдущий вопрос: Обнаружение в python клавиш, нажатых

Ответ 5

Для 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()

Ответ 6

Всегда есть sys.exit().

Системная библиотека в основной библиотеке Python имеет функцию выхода, которая очень удобна при создании прототипов. Код будет выглядеть следующим образом:

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()

Ответ 7

Это может быть полезно при установке pynput с помощью - 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