python - 如果 while 循环处于事件状态, turtle 图形不会响应 onkey() 命令

标签 python while-loop user-input turtle-graphics

我正在尝试制作一个游戏,其中 turtle 需要能够注册并响应用户输入(简化后,会出现一个字母,用户需要在键盘上单击它。所以如果它显示“b”用户输入“b”)。我只添加了字母a到f以使其在测试过程中更简单。它们每个都有一个函数,当按下字母并且程序正在监听它时,该函数就会执行。

一切都很顺利,直到我添加了一个 while 函数。目前 while 函数中没有任何内容(除了 pass 之外),但在我创建它之后,代码将不再响应用户输入。有人可以告诉我如何解决这个问题吗?我的最终目标是让程序始终监听用户输入,同时运行 while 循环并执行其代码。下面是我当前的代码

import signal, turtle

def timeout_handler(signal, frame): # End of timer function
    raise Exception('Time is up!')

signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(10) # Number inside is how long the game will last.

def hit_a():
    print("a registered")
def hit_b():
    print("b registered")
def hit_c():
    print("c registered")
def hit_d():
    print("d registered")
def hit_e():
    print("e registered")
def hit_f():
    print("f registered")

turtle.onkey(hit_a, "a")
turtle.onkey(hit_b, "b")
turtle.onkey(hit_c, "c")
turtle.onkey(hit_d, "d")
turtle.onkey(hit_e, "e")
turtle.onkey(hit_f, "f")
turtle.listen()


while True:
    pass
    # Add program here
turtle.mainloop()

编辑:我需要一段时间代码或至少一个循环来保持部分重复。在伪代码中,它看起来像这样:

Several turtles each write one letter somewhere on the screen
Program waits for user to input a letter
Award/deduct points based on if they got it right or wrong
go back to line 2 if they got it wrong.
repeat

我计划添加更多内容,但我首先需要让基础游戏运行起来。我知道如何编码的唯一方法是使用 while 循环。但使用它似乎是不可能的,因为它会阻止程序监听用户输入。请注意,我需要在 turtle 上完成这一切,而不是在终端上(如果在 Windows 上则为命令提示符),因为我将对字母进行颜色编码以显示要避免哪些字母以及要输入哪些字母。我该怎么写这个?

我还想快速提一下,我之前已经“避免”过这个问题。在下面的代码中,程序在 while 循环中响应用户输入。 (忽略问题和分配给 onkey() 的函数。这个想法是程序在循环中响应)。但是,我无法找出为什么在这段代码中程序在循环中响应,但在上面的代码中它没有注册任何用户输入

turtle.onkey(lower_game1_number, "s")
turtle.onkey(increase_game1_number, "w")
turtle.listen(xdummy=None, ydummy=None)

while True: # game1 is a turtle
    game1.write(first_game_num_display,False,"center",("Arial",30))
    game1_timer = random.randint(2,4)
    time.sleep(game1_timer)
    increase_game1_number()
    game1.undo()
    print(game1_timer)


mainloop()

最佳答案

除了 @martineau 提供的“永远不要在基于事件的环境中使用 while True:”建议之外,您无需将“信号”库拖到代码中使用 ontimer() 事件处理该问题。

I need a while code in there or at least a loop to keep a section repeating.

为了解决这个问题,我用一个简单的游戏替换了之前的示例代码,该游戏显示一个字母,并不断在屏幕上移动它并每两秒更改它的颜色,直到您键入该字母。之后,它将更改为不同的字母并继续:

from turtle import Screen, Turtle
from random import shuffle, randrange
from itertools import cycle

WIDTH, HEIGHT = 600, 600

FONT_SIZE = 36
FONT = ('Arial', FONT_SIZE, 'bold')

LETTERS = list("abcdefghijklmnopqrstuvwxyz")

COLORS = ['red', 'blue', 'green', 'magenta', 'cyan', 'black', 'orange', 'gray']

def play():
    global letter

    if hit == letter:
        letter = next(letters)

    turtle.clear()
    turtle.color(next(colors))
    turtle.goto(randrange(FONT_SIZE - WIDTH/2, WIDTH/2 - FONT_SIZE), randrange(FONT_SIZE - HEIGHT/2, HEIGHT/2 - FONT_SIZE))
    turtle.write(letter, font=FONT)

    screen.ontimer(play, 2000)

letters = LETTERS
shuffle(letters)
letters = cycle(letters)
letter = next(letters)

colors = COLORS
shuffle(colors)
colors = cycle(colors)

hit = None

screen = Screen()
screen.setup(WIDTH, HEIGHT)

turtle = Turtle(visible=False)
turtle.penup()

for character in LETTERS:

    def hit_character(character=character):
        global hit

        hit = character

    screen.onkey(hit_character, character)

screen.listen()

play()

screen.mainloop()

确保在键入之前单击窗口以使其监听输入。

希望这会给您一些如何在不使用 while True: 循环的情况下解决更复杂问题的想法。或者至少向您展示如何设置所有 onkey() 事件分配和处理程序,而无需为字母表中的每个字母重写相同的代码...

关于python - 如果 while 循环处于事件状态, turtle 图形不会响应 onkey() 命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54818435/

相关文章:

MySQL 程序接受用户输入并显示与结果相同的结果 - 不工作

qt - QT套接字等待用户输入

python - 在 Windows 上找不到通过 virtualenv 安装的模块

python - pySerial + SIM800/900 AT 命令 - 读缓冲区包含之前的写缓冲区数据

python - Virtualenv 未使用 workon 命令激活

c - 如何在键盘输入时立即停止C while循环而不继续下一步?

c - while 循环中的两个 scanf 语句无法正确读取

c - while循环中的奇怪输出(C语言)

C:提示输入一行并检查

python - 在迭代过程中修改数据帧不一致的行为