我正在寻找一种将多个图像与背景一起移动的方法。移动背景图像工作正常,但我无法弄清楚如何在顶部添加两个图像(它们立即消失),然后与背景一起移动。我想有一种简单的方法可以做到这一点?
我感谢任何提示!
from tkinter import *
import time
tk = Tk()
w = 1000
h = 800
pos = 0
canvas = Canvas(tk, width=w, height=h)
canvas.pack()
tk.update()
background_image = PhotoImage(file="bg.gif")
background_label = Label(tk, image=background_image)
background_label.place(x=0, y=0)
tk.update()
def addImages(files):
for f in files:
image = PhotoImage(file=f)
label = Label(tk, image=image)
label.place(x=files[f][0],y=files[f][1])
tk.update()
def move(xPos):
pos = background_label.winfo_x() - xPos
while background_label.winfo_x() > pos:
background_label.place(x=background_label.winfo_x()-25)
tk.update()
time.sleep(0.001)
img = {"file1.gif": [10,10], "file2.gif": [50,50]}
addImages(img)
move(100)
tk.mainloop()
答案 0 :(得分:0)
我很难理解你的代码。为什么要创建一个画布然后不使用它?您还使用tk.update()
填充了代码,其中大多数都是不必要的。但是,所描述的问题是因为您在函数内部创建了标签,并且当函数退出时,标签和图像之间的关联会被垃圾收集。您必须明确记住这种关联:
def addImages(files):
for f in files:
image = PhotoImage(file=f)
label = Label(tk, image=image)
label.image = image # Lets the label remember the image outside the function
label.place(x=files[f][0],y=files[f][1])
如果您要移动这些标签,可能需要对它们进行某种引用,否则您将无法解决这些问题。
完整示例
我将tk
更改为root
,因为tk
是通常用作tkinter别名的名称(例如。import tkinter as tk
),这会让人感到困惑。
我正在创建一个image_list
来保存对包含图片的标签的引用。后来我使用列表循环标签并移动它们。
构建GUI后,我等待1000毫秒才开始move
功能。此外,我一次只移动1个像素的图像,以便更清楚地看到动作。
from tkinter import *
import time
root = Tk()
root.geometry('800x600') # Setting window size instead of usin canvas to do that
pos = 0
background_image = PhotoImage(file="bg.gif")
background_label = Label(root, image=background_image)
background_label.place(x=0, y=0)
image_list = [] # List for holding references to labels with images
def addImages(files):
for f in files:
image = PhotoImage(file=f)
label = Label(root, image=image)
label.image = image # Remember the image outside the function
label.place(x=files[f][0],y=files[f][1])
image_list.append(label) # Append created Label to the list
def move(xPos):
pos = background_label.winfo_x() - xPos
while background_label.winfo_x() > pos:
background_label.place(x=background_label.winfo_x()-1)
for image in image_list: # Loop over labels in list
image.place(x=image.winfo_x()-1) # Move the label
root.update()
time.sleep(0.001)
img = {"file1.gif": [10,10], "file2.gif": [50,50]}
addImages(img)
root.after(1000, move, 100) # Waits 1 second and then moves images
root.mainloop()
顺便说一下; after
是一个比sleep
更受欢迎的函数,因为睡眠暂停程序直到它完成,而之后通过在一段时间后调用并且程序同时运行。但如果你对这个程序在移动过程中冻结,那么为什么不这样做呢。