Python键盘模块在循环内无法正常工作

时间:2019-03-15 15:26:27

标签: python python-3.x

我正在尝试创建一个简单的游戏,该游戏会产生数学问题,而用户的任务是确定它们是对还是错。 (例如2 + 2 = 6,对还是错?) 我正在使用键盘模块,如果用户认为问题是对的,我希望让用户按向左箭头,如果用户认为问题是对的,则要向右按。

import random
import keyboard


def addition_easy():
    x = random.randint(1, 6)
    y = random.randint(1, 6)
    z = x + y
    answer_correct = random.choice([True, False])
    if answer_correct == False:
        answer = (random.randint(2, 12))
    else:
        answer = z
    if answer == z:
        answer_correct = True

    print(f"{x} + {y} = {answer}")
    print("True or False?")

    while True:
        if keyboard.is_pressed('left'):
            user_answer = True
            break
        elif keyboard.is_pressed('right'):
            user_answer = False
            break

    if user_answer == answer_correct:
        return True
    else:
        return False

问题是,将此功能粘贴到循环后,只能按一次向左或向右。之后,无需等待我的按键就可以执行其余代码。

from problems import addition_easy

exercise_amount = int(input("How many exercises would you like to solve?"))

for exercise in range(1, exercise_amount + 1):
    addition_easy()

这将返回(输入5):

您想解决多少个练习? 5

6 +1 = 9

对还是错? //(在这里等我按“向左”或“向右”)

3 + 3 = 8

对还是错? //(从这里开始等待按键不停)

4 + 3 = 7

对还是错? //(相同,依此类推...)

2 + 3 = 3

对还是错?

1 + 2 = 3

对还是错?

每次打印出数学问题时,如何让它等待按键?

2 个答案:

答案 0 :(得分:0)

如果用户按住“左”键半秒,并且addition_easy在那半秒内执行了一百次,则keyboard.is_pressed('left')会为每个用户计算为True,即使用户只按一次“左”键即可。

通过告诉程序执行1000个问题,可以验证is_pressed是否不是永久地 认为按下了“左”键。向左按只会回答其中的20个。

一种可能的解决方案是更改循环,以使其等待直到随后释放密钥再继续。

while True:
    if keyboard.is_pressed('left'):
        user_answer = True
        while keyboard.is_pressed("left"):
            pass
        break
    elif keyboard.is_pressed('right'):
        user_answer = False
        while keyboard.is_pressed("right"):
            pass
        break

另一种可能的设计是使用keyboard.on_press_key,该方法仅在按键将状态从“未按下”变为“按下”时才触发(或者在经过自动重复时间后才触发,除非用户是故意这样做的)。您可以将其抽象为一个函数,以使您的addition_easy函数保持整洁:

import random
import keyboard
import time

def wait_for_keys(keys):
    key_pressed = None
    def key_press_event(key):
        nonlocal key_pressed
        key_pressed = key.name

    for key in keys:
        keyboard.on_press_key(key, key_press_event)

    while key_pressed is None:
        time.sleep(0.01)
    return key_pressed

def addition_easy():
    x = random.randint(1, 6)
    y = random.randint(1, 6)
    z = x + y
    answer_correct = random.choice([True, False])
    if answer_correct == False:
        answer = (random.randint(2, 12))
    else:
        answer = z
    if answer == z:
        answer_correct = True

    print(f"{x} + {y} = {answer}")
    print("True or False?")

    key = wait_for_keys(["left", "right"])
    user_answer = (key == "left")

    if user_answer == answer_correct:
        return True
    else:
        return False

exercise_amount = 1000

for exercise in range(1, exercise_amount + 1):
    addition_easy()

答案 1 :(得分:0)

不确定函数缩进是否正确。试试:

import random
import keyboard
def addition_easy():
    x = random.randint(1, 6)
    y = random.randint(1, 6)
    z = x + y
    answer_correct = random.choice([True, False])
    if answer_correct == False:
        answer = (random.randint(2, 12))
    else:
        answer = z
    if answer == z:
        answer_correct = True

    print(f"{x} + {y} = {answer}")
    print("True or False?")

    while True:
        if keyboard.is_pressed('left'):
            user_answer = True
            break
        elif keyboard.is_pressed('right'):
            user_answer = False
            break

    if user_answer == answer_correct:
        return True
    else:
        return False

exercise_amount = int(input("How many exercises would you like to solve?"))

for exercise in range(1, exercise_amount + 1):
    addition_easy()