Igor234
Igor234

Reputation: 389

display pairs of images using array of paths

I want to load a bunch of images, split them into pairs and then display those pairs in a window side by side (pair by pair). Also I'm gonna add a button to choose which pair to display.

    def select_files():
        files = filedialog.askopenfilenames(title="Select photo", filetypes=(("jpeg files", "*.jpg"), ("all files", "*.*")))   
        # many lines of code for the algorithm that splits images into pair
        pairs.append([photo1, photo2])      


    root = Tk()

    selectButton = Button(root, text="Select", command=select_files)
    selectButton.place(x=5, y=500)


    show_first = ImageTk.PhotoImage(img1)
    show_second = ImageTk.PhotoImage(img2)

    panel1 = Label(root, image=show_first)
    panel1.place(x=5, y=5)

    panel2 = Label(root, image=show_second)
    panel2.place(x=200, y=5)


    root.geometry("%dx%d+500+500" % (550, 550))
    root.mainloop()

But how do I pass images to show_first and show_second?

P.S. in the line pairs.append([photo1, photo2]) photo1 and photo2 are both lists with path stored in photo1[0] and image size in photo1[1]

Upvotes: 1

Views: 236

Answers (1)

gboffi
gboffi

Reputation: 25033

The problem is that tkinter callbacks ¹do not directly support arguments and ²ignore the return value. The issue can be solved ¹using a lambda with default arguments and ²using a mutable object (e.g., a list) as said default argument, because when the callback function modify it the changes are reflected in the caller scope.

E.g., you can go define select_files with an argument, a list, that is a mutable argument that you modify at will

def select_files(pairs):
    pairs.clear()  # this voids the content of the list
    # many lines of code for the algorithm that splits images into pairs
    pairs.append(['a.jpg', 'b.jpg'])

then, in your main, you modify the command=... to introduce a default argument

pairs = []
...
selectButton = Button(root, text = "Select",
                      command = lambda pairs=pairs: select_files(pairs))

so that, eventually, you can acces each pair of image filenames

for fn1, fn2 in pairs:
    ...

To show it in practice,

>>> def gp(pairs):
...     pairs.append([1,2])
... 
>>> pairs = []
>>> (lambda p=pairs: gp(p))() 
>>> pairs
[[1, 2]]
>>> 

and a counter example

>>> def gp(pairs):
...     pairs = [[1, 2]]
... 
>>> pairs = []
>>> (lambda p=pairs: gp(p))() 
>>> pairs
[]
>>> 

that shows that you should never assign to the function argument...

Upvotes: 1

Related Questions