简体   繁体   English

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

[英]Python keyboard module not working properly inside loop

I'm trying to create a simple game that creates math problems and the users task is to decide if they are true or false. 我正在尝试创建一个简单的游戏,该游戏会产生数学问题,而用户的任务是确定它们是对还是错。 (eg. 2 + 2 = 6, True or False?) I am using the keyboard module and I want to have the user press the left arrow key if he thinks that the problem is true, and the right one if he thinks that it's false. (例如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

The thing is, after I paste this function into a loop, I can only press left or right once. 关键是,将此功能粘贴到循环中后,只能按一次向左或向右。 After that the rest of the code is executed without waiting for my keypress. 之后,无需等待我的按键就可以执行其余代码。

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

This returns (for input of 5): 返回(输入5):

How many exercises would you like to solve? 您想解决多少练习? 5 5

6 + 1 = 9 6 +1 = 9

True or False? 对或错? //(Here it waits for me to press "left" or "right") //(这里等我按“向左”或“向右”)

3 + 3 = 8 3 + 3 = 8

True or False? 对或错? //(From here it doesn't stop to wait for a keypress) //(从这里开始等待按键不停)

4 + 3 = 7 4 + 3 = 7

True or False? 对或错? //(Same here and so on...) //(同这里,依此类推...)

2 + 3 = 3 2 + 3 = 3

True or False? 对或错?

1 + 2 = 3 1 + 2 = 3

True or False? 对或错?

How can I make it wait for a keypress every time it prints out a math problem? 每次打印出数学问题时,如何使它等待按键?

If the user holds down "left" for half a second, and addition_easy executes a hundred times in that half second, then keyboard.is_pressed('left') will evaluate to True for every one of them, even though the user only pressed "left" once. 如果用户按住“ left”按钮半秒钟,并且addition_easy在该半秒内执行了一百次,则即使用户仅按了“”, keyboard.is_pressed('left')也会对每个按钮求值为“ True”。离开”一次。

You can verify that is_pressed doesn't permanently consider "left" to be pressed by telling your program to do 1000 problems. 您可以通过告诉程序执行1000个问题来验证is_pressed不会永久认为要按下“左”键。 Pressing left will only answer about 20 of them. 向左按只会回答其中的20个。

One possible solution is to alter your loop so it waits until the key is subsequently released before continuing. 一种可能的解决方案是更改循环,以使其等待直到随后释放密钥再继续。

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

Another possible design is to use keyboard.on_press_key , which should only fire when the key changes state from "not pressed" to "pressed" (or when the auto repeat time elapses, which probably won't happen unless the user is doing it intentionally). 另一种可能的设计是使用keyboard.on_press_key ,它仅在按键将状态从“未按下”更改为“按下”时(或在经过自动重复时间后才会触发,除非用户有意进行,否则不会触发) )。 You can abstract this out to a function to keep your addition_easy function clean: 您可以将其抽象为一个函数,以使您的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()

Not sure if you indented your function correctly. 不知道您是否正确缩进了函数。 Try: 尝试:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM