Как я могу проверить нажатие клавиши в любой момент в течение всего 1000 *? - PullRequest
1 голос
/ 03 февраля 2020

Я пытаюсь сделать таймер, который отсчитывает до 0, а затем начинает считать. Я использую модули времени и клавиатуры. Модуль клавиатура от PyPi.

Все работает как положено, и я могу нажать кнопку, чтобы закрыть программу, но она работает только в начале каждой итерации. Есть ли способ проверить нажатие клавиши в любой момент, когда работает l oop? Нужно ли использовать другой модуль?

Это мой код:

import time
import keyboard

m = 2
s = 0
count_down = True

while True:
    if keyboard.is_pressed('q'):
        break
    print(f"{m} minutes, {s} seconds")
    if count_down:
        if s == 0:
            m -= 1
            s = 60
        s -= 1
    elif not count_down:
        s += 1
        if s == 60:
            m += 1
            s = 0
    if m == 0 and s == 0:
        count_down = False
    time.sleep(1)

Ответы [ 2 ]

1 голос
/ 03 февраля 2020

Если вы хотите выполнять какие-либо две вещи параллельно, независимо от других, вам следует рассмотреть возможность использования multiprocessing. Однако, даже если вы это сделаете, вашему l oop все равно нужно будет проверить, был ли зарегистрирован ключ в другом процессе, или вам необходимо принудительно завершить процесс, выполняющий l oop, что может привести к неожиданным результатам. .

Однако в вашем случае, поскольку нет побочных эффектов, таких как записываемые файлы, это будет работать:

import time
import keyboard
from multiprocessing import Process


def print_loop():
    m = 2
    s = 0
    count_down = True

    while True:
        print(f"{m} minutes, {s} seconds")
        if count_down:
            if s == 0:
                m -= 1
                s = 60
            s -= 1
        elif not count_down:
            s += 1
            if s == 60:
                m += 1
                s = 0
        if m == 0 and s == 0:
            count_down = False
        time.sleep(1)


def main():
    p = Process(target=print_loop)
    p.start()
    # this loop runs truly in parallel with the print loop, constantly checking
    while True:
        if keyboard.is_pressed('q'):
            break
    # force the print loop to stop immediately, without finishing the current iteration
    p.kill()


if __name__ == '__main__':
    main()
1 голос
/ 03 февраля 2020

Использование обратного вызова является обычным подходом в этом случае, вот решение:

import time
import keyboard

m = 2
s = 0
count_down = True

break_loop_flag = False

def handle_q_button():
    print('q pressed')
    global break_loop_flag
    break_loop_flag = True

keyboard.add_hotkey('q', handle_q_button)

while True:
    if break_loop_flag:
        break
    print(f"{m} minutes, {s} seconds")
    if count_down:
        if s == 0:
            m -= 1q
            s = 60
        s -= 1
    elif not count_down:
        s += 1
        if s == 60:
            m += 1
            s = 0
    if m == 0 and s == 0:
        count_down = False
    time.sleep(1)
...