【问题标题】:Issues with the "after" method in Python Tkinter [duplicate]Python Tkinter中“after”方法的问题[重复]
【发布时间】:2021-09-24 08:44:59
【问题描述】:

我正在用 Python Tkinter 制作一个记忆游戏。卡片翻转后,我正在使用 after 方法使我的代码中的重置功能延迟一秒钟,然后再将卡片翻转回来。它使函数永远等待。有人可以解释为什么会这样吗? 我的代码:

from tkinter import *
from random import choice

screen = Tk()
screen.title("Disney Princesses Memory Game")
width = screen.winfo_screenwidth()
height = screen.winfo_screenheight()
screen.geometry("%dx%d" % (width, height))
screen.configure(bg="#e0bce5")

title = Label(screen, text="Memory Game", font=("David", 50, "underline", "bold"), bg="#e0bce5")
title.place(x=400, y=20)

images_list = [
    PhotoImage(file="images/aurora.png"),
    PhotoImage(file="images/belle.png"),
    PhotoImage(file="images/cinderella.png"),
    PhotoImage(file="images/jasmine.png"),
    PhotoImage(file="images/mulan.png"),
    PhotoImage(file="images/rapunzel.png"),
    PhotoImage(file="images/snow white.png"),
    PhotoImage(file="images/tiana.png")
]

buttons_list = []
chosen_images = []
flipped = []
num_list = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
card = PhotoImage(file="images/card.png")
count = 0
no_press = False


def choose_images():
    for num in range(16):
        chosen_image = choice(images_list)
        num_list[num] += 1

        if num_list[num] > 2:
            num += 1
            continue
        else:
            chosen_images.append(chosen_image)


def replace_card(c, d):
    global flipped, count, no_press

    if no_press is True:
        return

    count += 1

    if count > 2:
        count = 0
        no_press = True
        sleep_secs()
    else:
        buttons_list[c][d].configure(image=chosen_images[d])
        flipped.append(buttons_list[c][d])


def reset():
    global card, no_press
    for element in flipped:
        element.configure(image=card)


def sleep_secs():
    global no_press
    screen.after(1000, reset)
    no_press = False


choose_images()
x = 100
y = 250
for i in range(2):
    buttons_list.append([])
    for j in range(8):
        a = Button(screen, image=card, command=lambda i=i, j=j: replace_card(i, j))
        x += 100
        a.place(x=x, y=y)
        buttons_list[i].append(a)
    y += 100
    x = 100

screen.mainloop()

对我来说,after 方法的奇怪之处在于,当我在一个较小的程序中实现它时它起作用了:

from tkinter import *

screen = Tk()
screen.geometry("600x800+30+10")
hi = Label(screen)
hi.place(x=20, y=20)


def reset():
    hi.configure(text="hi", font=("Ariel", 30))


def sleep_secs():
    screen.after(2000, reset)
    print(2)


sleep_secs()
screen.mainloop()

这是怎么回事?

【问题讨论】:

  • 你能解释一下让程序的一部分进入睡眠是什么意思吗?
  • tkinter 有自己的异步“在 N 秒内调用这个其他函数”机制。您应该使用它,而不是迄今为止给出的任何通用的、非 tkinter 感知的答案。 (这种情况是我们有接近重复机制的部分原因,以引导人们到某个地方,可用的答案集已经很全面,并且这些答案已经受益于评论反馈、投票等)
  • @Roni 看看this。我认为@CharlesDuffy 正在谈论.after 方法。但要小心:第一个参数以毫秒为单位。
  • @Roni 试试this
  • 真的,我会问一个minimal reproducible example 的问题,它衡量和量化 tkinter 中的.after 方法的延迟时间比它应该的要长得多。这是一个新的、不同的问题,也是一个有价值的问题。

标签: python tkinter


【解决方案1】:

试试异步功能:

from random import randint
import time
import asyncio


async def randn():
   await asyncio.sleep(3)
    return randint(1, 10)

【讨论】:

  • 您好,感谢您的回答。我对异步函数不是很熟悉。你能解释一下“return randint(1, 10)”有什么用吗?为什么我们需要返回一个 1 到 10 之间的随机整数?
  • 这只是一个例子,用你的函数的核心替换它。
  • 我认为这行不通...你能说得更具体点吗?
  • @MhamedBendenia 请解释您的答案中的代码是如何工作的。如果他们不理解它,它不会帮助 OP。如果 OP 使用您的代码但不理解它,它可以使他们的程序无法调试。
  • @Roni 我不知道asyncio 是如何工作的,但它是否使用另一个线程/进程来运行代码?如果是这样,那么您应该从asyncio 调用tkinter 函数,因为tkinter 不是线程安全的,有时它可能会崩溃。
猜你喜欢
  • 2014-02-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-16
  • 1970-01-01
  • 1970-01-01
  • 2014-11-03
  • 1970-01-01
相关资源
最近更新 更多