tkinter:用背景移动图像

时间:2018-05-03 07:24:10

标签: python 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()

1 个答案:

答案 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更受欢迎的函数,因为睡眠暂停程序直到它完成,而之后通过在一段时间后调用并且程序同时运行。但如果你对这个程序在移动过程中冻结,那么为什么不这样做呢。