如何在Python中执行文本动画?

问题描述

我正在用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()

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...