[英]How to animate a "movie style" credit reel with tkinter and canvas?
我正在嘗試使用 tkinter 的 canvas 創建一個“電影”風格的信用卷軸。 我想遍歷一個名稱列表並讓它們在 window 上滾動。 雖然我已經成功地獲得了一個要滾動的名稱,但我正在努力迭代多個名稱。
感謝您的幫助,並對我的任何嚴重疏忽表示歉意。
from tkinter import *
import time
window = Tk()
window.geometry("1920x1080")
window.title("Window 1")
canvas1 = Canvas(window, width=1920, height=1080, bg="green", bd=0, highlightthickness=0, relief='ridge')
canvas1.pack()
class CreditList:
def __init__(self, text):
self.text = text
self.location = 1080
def credit_roll_function(self):
text = canvas1.create_text(960,self.location, text=self.text, anchor=S, fill="black",
font="Time 40")
while True:
canvas1.move(text, 0, -3)
window.update()
time.sleep(.03)
credit_list = ["First Name", "Second Name", "Third Name"]
for credit in credit_list:
item = CreditList(credit)
item.credit_roll_function()
window.mainloop()
這是一種簡單的方法,它使用通用小部件after()
方法而不是調用干擾 tkinter 的 mainloop( time.sleep()
的mainloop()
。 每次調用類的roll_credits()
方法時,它會將文本向上移動一點,如果文本尚未位於 window 的頂部,則會安排對自身的另一個調用。
import tkinter as tk
from tkinter.constants import *
class CreditList:
def __init__(self, text):
self.location = HEIGHT
self.text = canvas.create_text(960, self.location, text='\n'.join(text),
anchor=S, fill='black', font='Time 40')
def roll_credits(self):
xl, yt, xr, yb = canvas.bbox(self.text)
if yb <= 0: # Completely off top of screen?
canvas.pack_forget()
tk.Button(text='Quit', font=('Arial', 20), relief=GROOVE, bg='orange',
command=window.quit).place(x=WIDTH/2, y=HEIGHT/2, anchor=NW)
return # Stop.
canvas.move(self.text, 0, -3)
self.location -= 3
window.after(DELAY, self.roll_credits) # Keep going.
DELAY = 10 # Millisecs.
window = tk.Tk()
window.attributes('-fullscreen', True)
window.update_idletasks()
WIDTH, HEIGHT = window.winfo_width(), window.winfo_height() # Get screen size.
window.geometry(f'{WIDTH}x{HEIGHT}+0+0')
window.title('Window 1')
canvas = tk.Canvas(window, width=WIDTH, height=HEIGHT, bg='green', bd=0,
highlightthickness=0, relief='ridge')
canvas.pack()
credits = 'First Name', 'Second Name', 'Third Name'
cl = CreditList(credits)
window.after(DELAY, cl.roll_credits) # Start rolling credits "loop".
window.mainloop()
如果您為所有文本項賦予相同的標簽,則可以同時移動它們。 另一種解決方案是創建一個文本項,該文本項是通過用換行符連接所有字符串來創建的。
例如,以下代碼說明了如何使用給定標簽創建所有項目,然后每 33 毫秒一次將它們全部移動一個像素,直到它們不再可見。
import tkinter as tk
class CreditList(tk.Canvas):
def __init__(self, master, **kwargs):
super().__init__(master, **kwargs)
def roll_credits(self, credit_list):
x = self.winfo_width() // 2
y = self.winfo_height()
temp = self.create_text(0,0,text="Hello")
bbox = self.bbox(temp)
self.delete(temp)
lineheight = bbox[3]-bbox[1]
linespacing = 4
for credit in credit_list:
self.create_text(x, y, text=credit, anchor="n", tags=("credit",))
y += lineheight + linespacing
self._animate()
def _animate(self):
self.move("credit", 0, -1)
x0, y0, x1, y1 = self.bbox("credit")
if y1 > 0:
self.after(33, self._animate)
root = tk.Tk()
credits = CreditList(root)
credits.pack(side="top", fill="both", expand=True)
credit_list = 'First Name', 'Second Name', 'Third Name'
root.after(1000, credits.roll_credits, credit_list)
root.mainloop()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.