简体   繁体   中英

Tkinter: Display image after opening from dialog

This is the first program I'm writing utilizing Tkinter, so I apologize in advance if my questions are a bit naive.

I have the following:

class Example(Frame):
def __init__(self, master=None):
    Frame.__init__(self,master)

    menubar = Menu(self)
    master.config(menu=menubar)
    self.centerWindow(master)
    self.Top_Bar(menubar,master)
    self.pack(fill = BOTH, expand = 1)

def Top_Bar(self,menubar,master):
    fileMenu = Menu(menubar,tearoff=False)
    menubar.add_cascade(label="File",menu=fileMenu)
    fileMenu.add_command(label="Open",command = self.open_file)
    fileMenu.add_command(label="Exit",command = self.quit)

    fileMenu = Menu(menubar,tearoff=False)
    menubar.add_cascade(label="Edit",menu=fileMenu)

    fileMenu = Menu(menubar,tearoff=False)
    menubar.add_cascade(label="Shortcuts",menu=fileMenu)

    fileMenu = Menu(menubar,tearoff=False)
    menubar.add_command(label="About",command = Message_About)

Notice that I have self.open_file as a command, which is itself a function:

def open_file(self):
    """ A function that opens the file dialog and allows a user to select a single file, displaying it on the page """
    global filename
    filename = []
    filename.append(str(unicodedata.normalize("NFKD",tkFileDialog.askopenfilename(filetypes=[("Astronomical Data","*.fit;*fits")])).encode("ascii","ignore")))

    for i in filename:
        stretch_type = "linear"
        image_manipulation_pyfits.create_png(i,stretch_type)
        x = Image.open("file.png")
        Label(image = x).pack()

I'm certain there's a shorter, more efficient way of writing this function, but that isn't my primary goal at this point -- it's just to get everything to work. My goal is to take this image x and display it in the Tkinter window. It gives me the error

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\python27\lib\lib-tk\Tkinter.py", line 1486, in __call__
    return self.func(*args)
  File "tkinter1.py", line 125, in open_file
    Label(image = x).pack()
  File "C:\python27\lib\lib-tk\ttk.py", line 766, in __init__
    Widget.__init__(self, master, "ttk::label", kw)
  File "C:\python27\lib\lib-tk\ttk.py", line 564, in __init__
    Tkinter.Widget.__init__(self, master, widgetname, kw=kw)
  File "C:\python27\lib\lib-tk\Tkinter.py", line 2055, in __init__
    (widgetName, self._w) + extra + self._options(cnf))
TclError: image specification must contain an odd number of elements

For clarity, the prior function simply takes an input .fits image (selected from the dialog box that pops up) and applies the linear stretch, then saves it as a .png image to the same directory under the name "file.png".

I've Googled for the past day or so and haven't been able to find any threads on this error.

One solution I have found:

        x = Image.open("file.gif")
        x = ImageTk.PhotoImage(x)
        label = Label(image = x)
        label.image = x
        label.pack()
  • Save the image as a .gif and open
  • Need to use PhotoImage from ImageTk.

I would comment if I could, but just a note about @bjd2385's answer. In his case, label.image = x saves a reference of the image, however if this line of code is omitted, then you would need to save a reference by using self , if using classes in your design pattern. Instead of im = ImageTk.PhotoImage("...") it would then be self.im = ImageTk.PhotoImage("...") otherwise it can get garbage collected and still display an outline of where the image would be, but not actually have an image present.

Also, you can directly open an image from the PhotoImage call. I'm not sure of the complete limitations of image files possible to be used, but I know you can use .gif and .png. Here's his answer reworked for Python3.4:

    import tkinter

    self.img = ImageTk.PhotoImage(file = "./images/file.png")
    label = Label(image = self.img)
    label.image = self.img # this line can be omitted if using the 'self' method to save a reference
    label.pack()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM