python-3.xtkinter

Displaying my image in an Image Viewer I got from Git Hub


I found an Image Viewer (IV) application on GitHub which I want to use in my own Python 3 project.

The IV has a File->Open dialogue using tk.filedialog.askopenfilename to allow users to select the image to open, but I want the IV to open my own image in a TopLevel() window by calling it's set_image() method using the path to my image (ultimately I want to display a pre-defined list of images using the IV).

The only way I can get this to work is having my own code call tk.filedialog.askopenfilename and then cancelling the dialogue.

The tk.filedialog.askopenfilename seems to be doing more than just opening a dialogue - I'd like to understand how to open my image without having to call tk.filedialog.askopenfilename first.

The Git Hub Image Viewer code is quite long, so here is a link to it: https://github.com/ImagingSolution/PythonImageViewer

Here is my code:

import tkinter as tk
from tkinter import ttk
from ImageViewer import Application

def display_image():
    top=tk.Toplevel()
    top.attributes('-topmost', 'true')
    iv = Application(master=top)

    # MyImage is displayed only if this line is included
    filename = tk.filedialog.askopenfilename()

    iv.set_image('C:/MyImage.jpg')

# Display my image when the button is clicked
root = tk.Tk()
root.geometry('150x100')

button_open = ttk.Button(
    root,
    text="Display Image",
    command=display_image)

button_open.pack(padx=20, side=tk.LEFT)

root.mainloop()

Solution

  • If you print out the width and height of the canvas inside Application after the line iv = Application(master=top):

    def display_image():
        ...
        iv = Application(master=top)
        print(iv.canvas.winfo_width(), iv.canvas.winfo_height()) # show the canvas size
        ...
    

    you will get 1 1 since the canvas is not fully initialized. So the image loaded by the line iv.set_image(...) will be resized to 1x1 and not visible. It can be verified by printing the size of the image after the line iv.set_image(...):

    def display_image():
        ...
        iv.set_image('C:/MyImage.jpg')
        print(iv.image.width(), iv.image.height()) # show the image size
    

    To fix the above issue, you can call iv.update() after creating iv:

    def display_image():
        top = tk.Toplevel()
        top.attributes('-topmost', 'true')
    
        iv = Application(master=top)
        iv.update() # make sure all widgets are initialized fully
    
        iv.set_image("C:/MyImage.jpg")