Imageslider 3.0 – Tkinter app to show images like in a presentation

Some time ago I made this little app to show images with tkinter, in a canva, letting you browse the image through a listbox on the left. You can go here to see the original code:

Tkinter: ImageBrowser 2 – with canvas

There is also another version that uses a label to show the images.

The new version… let’s call it imageslider 1.3

In this version the images fits the screen also when you change the window size. This is obtained binding to <Configure> the root, so that when you change the window size dragging the window it calls the showimg function that you see here below:

def showimg(event):
    n = lst.curselection()
    filename = lst.get(n)
    im = Image.open(filename)
    im = im.resize((get_window_size()), Image.ANTIALIAS)
    img = ImageTk.PhotoImage(im)
    w, h = img.width(), img.height()
    canvas.image = img
    canvas.config(width=w, height=h)
    canvas.create_image(0, 0, image=img, anchor=tk.NW)
    root.bind("<Configure>", lambda x: showimg(x))

What this function does:

1. get the number of the list selected
2. get the item selected (a string with filename)
3. open the file with Image.open
4. resize it to screen w and h
5. make the canvas the same size
6. add to canvas the image
7. bind to configure the root

The key thing here, is configure. Everytime you change the window size makes the image and canvas be like the root size.

A shrinked version

and even smaller

As you can see, the image strecthes like the window.

The whole code for imageslider 1.3

import tkinter as tk
import glob
from PIL import Image, ImageTk
import os

def insertfiles():
    # lst.delete(0, tk.END)
    for filename in glob.glob("*.png"):
        lst.insert(tk.END, filename)

def delete_item(event):
    n = lst.curselection()
    os.remove(lst.get(n))
    lst.delete(n)


def get_window_size():
    if root.winfo_width() > 200 and root.winfo_height() >30:
        w = root.winfo_width() - 200
        h = root.winfo_height() - 30
    else:
        w = 200
        h = 30
    return w, h


def showimg(event):
    n = lst.curselection()
    filename = lst.get(n)
    im = Image.open(filename)
    im = im.resize((get_window_size()), Image.ANTIALIAS)
    img = ImageTk.PhotoImage(im)
    w, h = img.width(), img.height()
    canvas.image = img
    canvas.config(width=w, height=h)
    canvas.create_image(0, 0, image=img, anchor=tk.NW)
    root.bind("<Configure>", lambda x: showimg(x))



root = tk.Tk()

root.geometry("800x600+300+50")
lst = tk.Listbox(root, width=20)
lst.pack(side="left", fill=tk.BOTH, expand=0)
lst.bind("<<ListboxSelect>>", showimg)
lst.bind("<Control-d>", delete_item)
insertfiles()
canvas = tk.Canvas(root)
canvas.pack()

root.mainloop()

Use SVG instead of PNG! Great quality resizing

I had this idea to use svg files instead of png, to have a perfect resizing. I send you to this post to understand how to get an svg into tkinter.

import tkinter as tk
import glob
from PIL import Image, ImageTk
import os
from svglib.svglib import svg2rlg
from reportlab.graphics import renderPM


def insertfiles():
    "loads the list of files in the directory"
    for filename in glob.glob("*.svg"):
        lst.insert(tk.END, filename)


def delete_item(event):
    "Deletes a file in the list: called by lst.bind('<Control-d>', delete_item)"
    n = lst.curselection()
    os.remove(lst.get(n))
    lst.delete(n)


def get_window_size():
    "Returns the width and height of the screen to set images and canvas alike it: called by root.bind <Configure>"
    root_w = root.winfo_width()
    if root.winfo_width() > 200 and root.winfo_height() >30:
        w = root.winfo_width() - 200
        h = root.winfo_height() - 30
    else:
        w = 200
        h = 30
    return w, h


def showimg(event):
    "takes the selected image to show it, called by root.bind <Configure> and lst.bind <<ListboxSelect>>"
    n = lst.curselection()
    filename = lst.get(n)
    drawing = svg2rlg(filename)
    renderPM.drawToFile(drawing, "temp.png", fmt="PNG")    
    im = Image.open("temp.png")
    im = im.resize((get_window_size()), Image.ANTIALIAS)
    img = ImageTk.PhotoImage(im)
    w, h = img.width(), img.height()
    canvas.image = img
    canvas.config(width=w, height=h)
    canvas.create_image(0, 0, image=img, anchor=tk.NW)
    root.bind("<Configure>", lambda x: showimg(x))



root = tk.Tk()

root.geometry("800x600+300+50")
lst = tk.Listbox(root, width=20)
lst.pack(side="left", fill=tk.BOTH, expand=0)
lst.bind("<<ListboxSelect>>", showimg)
lst.bind("<Control-d>", delete_item)
insertfiles()
canvas = tk.Canvas(root)
canvas.pack()

root.mainloop()

The video presentation

Here is the repository on github


Subscribe to the newsletter for updates
Tkinter templates
Avatar My youtube channel

Twitter: @pythonprogrammi - python_pygame

Videos

Speech recognition game

Pygame's Platform Game

Other Pygame's posts

Published by pythonprogramming

Started with basic on the spectrum, loved javascript in the 90ies and python in the 2000, now I am back with python, still making some javascript stuff when needed.