Search code examples
pythontkintertkinter-canvas

Can I change multiple images at the same time?


As I mentioned in my last question I'm making a conveyor belt that picks up images from a folder and makes them move from left to right. An unexpected problem rose, I'm already changing images with canvas.image = (New image) to animate the conveyor belt and I thought that I could do the same with the other objects:

#Import
import os
import random 
from PIL import Image, ImageTk
from tkinter import Tk, Canvas, PhotoImage, NW
from tkinter import Label

# folder path
dir_path = r'C:\Users\Usuario\Downloads\Experiment'

#------------------------------------------------------------Select Random Image--------------------------------------------------------

imgExtension = ["webp","png"] #Image Extensions to be chosen from
allImages = list()

def Makelist(directory):
    for img in os.listdir(directory): #Lists all files
        ext = img.split(".")[len(img.split(".")) - 1]
        if (ext in imgExtension):
            allImages.append(img)
    return allImages

Makelist(dir_path)
global potatoes
potatoes = allImages
choice = random.randint(0, len(potatoes) - 1)
randomImage = potatoes[choice] #Image chosen
print(randomImage)
potatoes.remove(randomImage)

#------------------------------------------------------------Canvas---------------------------------------------------------------
root = Tk()
root.attributes('-transparentcolor','#f0f0f0')

canvas = Canvas(root, width = root.winfo_screenwidth(), height=300)
canvas.pack()
#-------------------------------------------------------Conveyor belt gif------------------------------------------------------------
file = r'C:\Users\Usuario\Downloads\Python\Cinta'
allImages = []
Makelist(file)
conveyor = allImages
global current_con
current_con = 0
print(conveyor)
conveyori = Image.open(file+"/"+conveyor[current_con])
conveyorimg = ImageTk.PhotoImage(conveyori)
conveyor_canva = canvas.create_image(0, 0, anchor=NW, image = conveyorimg)
conveyor_label = Label(canvas, image = conveyorimg)
conveyor_label = conveyorimg
def animation():
    global current_con
    if (current_con < 3):
        current_con += 1
    else:
        current_con = 0
    conveyori = Image.open(r'C:/Users/Usuario/Downloads/Python/Cinta/'+conveyor[current_con])
    conveyorimg = ImageTk.PhotoImage(conveyori)
    canvas.itemconfig(conveyor_canva, image = conveyorimg)
    canvas.image  = conveyorimg
    canvas.after(105, animation)
#-------------------------------------------------------------Potato a image setup------------------------------------------------------------------
im_O = Image.open(r'C:/Users/Usuario/Downloads/Experiment/'+ randomImage)
new_image = im_O.resize((100, 100))
potimg = ImageTk.PhotoImage(new_image)
potato_label = Label(canvas, image = potimg)
potato_label = potimg
#-----------------------------------------------------Positioning the Image inside the canvas-------------------------------------------------------
imga = canvas.create_image(root.winfo_screenwidth()+20, 100, anchor=NW, image = potimg)
#---------------------------------------------------------------Potato a movement setup--------------------------------------------------------------
global pos
pos = root.winfo_screenwidth()+20
def move_imga():
    global pos
    global potatoes
    pos -= 5
    # move the image
    canvas.move(imga, -5, 0)
    if (pos < -90):
        #Potato change
        if (potatoes == []): #If there are no images left make a new list
            allImages = []
            Makelist(dir_path)
            potatoes = allImages
        #Ok now let's actually change the image
        choice = random.randint(0, len(potatoes) - 1)
        randomImage = potatoes[choice] #Image chosen
        print(randomImage)
        potatoes.remove(randomImage)
        #Do all the stuff, resize it, etc
        im_O = Image.open(r'C:/Users/Usuario/Downloads/Experiment/'+ randomImage)
        new_image = im_O.resize((100, 100))
        potimg = ImageTk.PhotoImage(new_image)
        canvas.itemconfig(imga, image = potimg)
        canvas.image = potimg
        canvas.moveto(imga, root.winfo_screenwidth()+20, 100)
        pos = root.winfo_screenwidth()+20
    # move again after 25 ms (0.025s)
    canvas.after(25, move_imga)
#----------------------------------------------------------Starts the GUI------------------------------------------------------------
move_imga()
animation()
root.mainloop()

What I tried was: When a potato goes off the screen a new image is picked from the array, then I open the image, change the image and teleport it back to the begining. But it doesen't work. I don't really know why but I think it's probably because the conveyor belt is also using the same function to change sprites


Solution

  • What I tried was: When a potato goes off the screen a new image is picked from the array, then I open the image, change the image and teleport it back to the begining. But it doesen't work

    Your problem can be fixed.

    • Comment out Label widgets on line 65 and 66. It doesn't do anything.
    • On line 68, remove keyword image = potimg, It will update on line on line 98.
    • On line 74, Add global potmig. Like this: global potatoes, potimg
    • on line 93, comment out #canvas.itemconfig(imga, image = potimg)
    • On line 98, add this canvas.itemconfig(imga, image = potimg. Put this outside of first if-else block, and before canvas.after.

    Snippet:

    #Import
    import os
    import random 
    from PIL import Image, ImageTk
    from tkinter import Tk, Canvas, PhotoImage, NW
    from tkinter import Label
    
    # folder path
    dir_path = r'C:\Users\Usuario\Downloads\Experiment'
    
    #------------------------------------------------------------Select Random Image--------------------------------------------------------
    
    imgExtension = ["webp","png"] #Image Extensions to be chosen from
    allImages = list()
    
    def Makelist(directory):
        for img in os.listdir(directory): #Lists all files
            ext = img.split(".")[len(img.split(".")) - 1]
            if (ext in imgExtension):
                allImages.append(img)
        return allImages
    
    Makelist(dir_path)
    global potatoes
    potatoes = allImages
    choice = random.randint(0, len(potatoes) - 1)
    randomImage = potatoes[choice] #Image chosen
    print(randomImage)
    potatoes.remove(randomImage)
    
    #------------------------------------------------------------Canvas---------------------------------------------------------------
    root = Tk()
    root.attributes('-transparentcolor','#f0f0f0')
    
    canvas = Canvas(root, width = root.winfo_screenwidth(), height=300)
    canvas.pack()
    #-------------------------------------------------------Conveyor belt gif------------------------------------------------------------
    file = r'C:\Users\Usuario\Downloads\Python\Cinta'
    allImages = []
    Makelist(file)
    conveyor = allImages
    global current_con
    current_con = 0
    print(conveyor)
    conveyori = Image.open(file+"/"+conveyor[current_con])
    conveyorimg = ImageTk.PhotoImage(conveyori)
    conveyor_canva = canvas.create_image(0, 0, anchor=NW, image = conveyorimg)
    conveyor_label = Label(canvas, image = conveyorimg)
    conveyor_label = conveyorimg
    def animation():
        global current_con
        if (current_con < 3):
            current_con += 1
        else:
            current_con = 0
        conveyori = Image.open(r'C:/Users/Usuario/Downloads/Python/Cinta/' + conveyor[current_con])
        conveyorimg = ImageTk.PhotoImage(conveyori)
        canvas.itemconfig(conveyor_canva, image = conveyorimg)
        canvas.image  = conveyorimg
        canvas.after(105, animation)
    #-------------------------------------------------------------Potato a image setup------------------------------------------------------------------
    im_O = Image.open(r'C:/Users/Usuario/Downloads/Experiment/' + randomImage)
    new_image = im_O.resize((100, 100))
    potimg = ImageTk.PhotoImage(new_image)
    #potato_label = Label(canvas, image = potimg)
    #potato_label = potimg
    #-----------------------------------------------------Positioning the Image inside the canvas-------------------------------------------------------
    imga = canvas.create_image(root.winfo_screenwidth()+20, 100, anchor=NW)
    #---------------------------------------------------------------Potato a movement setup--------------------------------------------------------------
    global pos
    pos = root.winfo_screenwidth()+20
    def move_imga():
        global pos
        global potatoes, potimg
        pos -= 5
        # move the image
        canvas.move(imga, -5, 0)
        if (pos < -90):
            #Potato change
            if (potatoes == []): #If there are no images left make a new list
                allImages = []
                Makelist(dir_path)
                potatoes = allImages
            #Ok now let's actually change the image
            choice = random.randint(0, len(potatoes) - 1)
            randomImage = potatoes[choice] #Image chosen
            print(randomImage)
            potatoes.remove(randomImage)
            #Do all the stuff, resize it, etc
            im_O = Image.open(r'C:/Users/Usuario/Downloads/Experiment/' +  randomImage)
            new_image = im_O.resize((100, 100))
            potimg = ImageTk.PhotoImage(new_image)
            #canvas.itemconfig(imga, image = potimg)
            canvas.image = potimg
            canvas.moveto(imga, root.winfo_screenwidth()+20, 100)
            pos = root.winfo_screenwidth()+20
        # move again after 25 ms (0.025s)
        canvas.itemconfig(imga, image = potimg)
        canvas.after(25, move_imga)
    #----------------------------------------------------------Starts the GUI------------------------------------------------------------
    move_imga()
    animation()
    root.mainloop()
    

    Output:

    canada.png <--- first start.
    ['canada-logo.png', 'canada.png', 'canada_1.png', 'canada_2.png', 'card.png', 'Chess_queen.png', 'cricket.png', 'fia_logo.png', 'guyana.png', 'laser.png', 'NOKIA.png', 'p11.png', 'p12.png', 'p13.png', 'p14.png', 'p15.png', 'p16.png', 'p17.png', 'p18.png', 'p19.png', 'p2.png', 'p20.png', 'p21.png', 'p22.png', 'p23.png', 'supra-logo.png', 'supra.png', 'turks_and_caicos.png']
    
    You will see all outputs in below:
    fia_logo.png
    p19.png
    p23.png
    supra-logo.png
    supra.png
    turks_and_caicos.png
    p18.png