Мне сложно понять ваш код. Зачем создавать холст, а потом не использовать его? Вы также замусорили свой код 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
для хранения ссылок на метки, содержащие изображения. Позже я использую список, чтобы перебрать метки и переместить их.
После того, как я построил графический интерфейс, я жду 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
, так как режим сна приостанавливает работу программы до ее завершения, тогда как после работы выполняется вызов через некоторое время, и программа тем временем запускается. Но если вы согласны с тем, что во время перемещения программа зависает, то почему бы и нет.