问题描述
我正在用python创建一个GUI应用程序,这是一个“ Lingo”文字游戏。在GUI的主屏幕上,我试图使字符每1秒出现在屏幕上一次。但是,我是这种Python编程的新手,不确定如何做到这一点。我要同时出现以下几个字符,这些单词组成以下单词。
“线索” “大” “列表” “腰部” “行话”
此刻,这些字符在GUI屏幕上出现在不同的x和y位置。例如,对于Leads一词,我希望1秒后出现“ l”,然后是“ e”,依此类推。我打算让这些字符在1秒钟后顺序出现在当前位置。我试图使用time.sleep()和after()函数,但是无法使用它们。关于如何执行此动画的任何建议?基本上,我试图将GUI游戏首次运行时将用户玩游戏作为背景动画来实现。
import tkinter as tk
from tkinter import ttk
import tkinter.font as tkFont
import numpy as np
import time
root = tk.Tk()
canvas = tk.Canvas(root,height = '500',width = '500')
canvas.pack()
#Create Title Lingo Balls
canvas.create_oval(30,10,100,80,outline = "medium blue",fill = "medium blue",width = 2)
canvas.create_oval(120,190,width = 2)
canvas.create_oval(210,280,width = 2)
canvas.create_oval(300,370,width = 2)
canvas.create_oval(390,460,width = 2)
#Print Letters Inside of Lingo Ball Circles
letterfont = tkFont.Font(size = 30)
l = canvas.create_text((65,46),text= "L",font = letterfont,fill = "white")
i = canvas.create_text((155,text= "I",fill = "white")
n = canvas.create_text((245,text= "N",fill = "white")
g = canvas.create_text((335,text= "G",fill = "white")
o = canvas.create_text((425,text= "O",fill = "white")
#Create Homepage Game Board
canvas.create_rectangle(210,220,290,outline = "blue",fill = "blue",width = 200)
canvas.create_line(164,120,164,390,fill = "white")
canvas.create_line(218,218,fill = "white")
canvas.create_line(272,272,fill = "white")
canvas.create_line(326,326,fill = "white")
canvas.create_line(110,174,380,228,282,336,fill = "white")
canvas.create_rectangle(110,outline = "white",fill = "red") #create red squares for correctly guessed letters
canvas.create_rectangle(110,fill = "red")
canvas.create_rectangle(110,fill = "red")
canvas.create_rectangle(272,fill = "red")
canvas.create_rectangle(164,fill = "red")
canvas.create_rectangle(218,fill = "red")
canvas.create_rectangle(326,fill = "yellow") #create yellow squares for guessed letters that are in word,but out of place
canvas.create_rectangle(218,fill = "yellow")
canvas.create_rectangle(272,fill = "yellow")
l = canvas.create_text((137,147),fill = "white")
e = canvas.create_text((191,text= "E",fill = "white")
a = canvas.create_text((245,text= "A",fill = "white")
d = canvas.create_text((299,text= "D",fill = "white")
s = canvas.create_text((353,text= "S",fill = "white")
l = canvas.create_text((137,201),fill = "white")
a = canvas.create_text((191,fill = "white")
r = canvas.create_text((245,text= "R",fill = "white")
g = canvas.create_text((299,fill = "white")
e = canvas.create_text((353,fill = "white")
l = canvas.create_text((137,255),fill = "white")
i = canvas.create_text((191,fill = "white")
s = canvas.create_text((245,fill = "white")
t = canvas.create_text((299,text= "T",309),fill = "white")
o = canvas.create_text((191,fill = "white")
i = canvas.create_text((245,fill = "white")
n = canvas.create_text((299,363),fill = "white")
o = canvas.create_text((353,fill = "white")
root.mainloop()
解决方法
tkinter中动画的基本概念是从编写一个可以完成动画一帧的函数开始,然后让另一个函数调用它,然后安排自己在将来再次调用。
因此,让我们从名为draw
的函数开始,该函数在给定的坐标下在框中绘制单个字母:
def draw(canvas,char,x,y,color):
"""Draw one character in a box at the given coordinate"""
text_id = canvas.create_text(x,text=char,anchor="nw",font=letterfont)
x0,y0,x1,y1 = canvas.bbox(text_id)
box_id = canvas.create_rectangle(x0-1,y0-1,x1+1,y1+1,fill=color,outline="black")
canvas.lift(text_id,box_id)
接下来,编写一个通过after
调用此函数的函数。在这种情况下,它会一次从字符串中拉出一个字符,并继续每秒这样做一次,直到字符串完全显示为止。
def animate(canvas,string,color):
"""Draw each character in the string at one second intervals. """
draw(canvas,string[0],color)
if len(string) > 1:
string = string[1:]
canvas.after(1000,animate,canvas,x+width,color)
我不建议您完全按原样使用此代码。即使您已经预先计算了坐标,它也会计算每个字母的坐标,此外,最好将其实现为类或类的一部分。
无论如何,该技术保持不变,并取决于animate
函数与after
一起进行调度,然后调用其他函数执行一帧动画。
这是完整程序中的上述代码:
import tkinter as tk
import tkinter.font as tkFont
root = tk.Tk()
canvas = tk.Canvas(root)
canvas.pack(fill="both",expand=True)
letterfont = tkFont.Font(size = 30)
width = letterfont.measure("0")
def draw(canvas,box_id)
def animate(canvas,color)
animate(canvas,"Leads",2,"bisque")
root.mainloop()
,
要一次显示一个字符,可以在开始时将文本对象设置为隐藏,然后使用计时器按顺序显示每个字母。
lstltr = [ # store all letter object ids in list
canvas.create_text((137,147),text= "L",font = letterfont,fill = "white",state= tk.HIDDEN),canvas.create_text((191,text= "E",canvas.create_text((245,text= "A",canvas.create_text((299,text= "D",canvas.create_text((353,text= "S",............
canvas.create_text((137,363),text= "I",text= "N",text= "G",text= "O",state= tk.HIDDEN)
]
def countdown(idx):
# change text in label
if idx < len(lstltr):
canvas.itemconfigure(lstltr[idx],state=tk.NORMAL) # show letter object
root.after(100,countdown,idx+1) # 1/10 second
countdown(0) # start timer
root.mainloop()