tkinter:移动带有背景的图像



我正在寻找一种将多个图像与背景一起移动的方法。移动背景图像工作正常,但我不知道如何在顶部添加两个图像(它们立即消失(,然后与背景一起移动。我想有一个简单的方法可以做到这一点吗?

我感谢任何提示!

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()

我很难理解你的代码。为什么要创建画布然后不使用它?你还用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更改为roottk因为该名称通常用作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更受欢迎的功能,因为睡眠暂停程序直到它完成,而之后工作通过一段时间后进行调用并且程序同时运行。但是,如果您同意程序在移动过程中冻结,那为什么不呢。

最新更新