0

I'm trying to open a file with PIL and tkinter. Im using this code:

import tkinter as tk
from PIL import Image,ImageTk
from tkinter import *
intWidth=20
intHeight=5

class SampleApp(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)



        # the container is where we'll stack a bunch of frames
        # on top of each other, then the one we want visible
        # will be raised above the others
        container = tk.Frame(self)
        container.grid(row=0,column=0)#pack(side="top", fill="both", expand=True)



        self.frames = {}
        for F in (StartPage, Departure, PageTwo):
            page_name = F.__name__
            frame = F(parent=container, controller=self)
            self.frames[page_name] = frame
            frame.config(bg='#FBC311')

            # put all of the pages in the same location;
            # the one on the top of the stacking order
            # will be the one that is visible.
            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame("StartPage")

    def show_frame(self, page_name):
        '''Show a frame for the given page name'''
        frame = self.frames[page_name]
        frame.tkraise()


class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        for row in range(9):
            self.grid_rowconfigure(row, weight=1)
            Button(self,text="Button %d"%(row), bg = '#005ca0', fg = 'white', font = "Verdana 10", width = intWidth, height = intHeight).grid(row = row,column = 0,sticky = E+W)

        for c in range(9):
            self.grid_columnconfigure(c, weight=1)
            Button(self,text="Button %d"%(c), bg = '#005ca0', fg = 'white', font = "Verdana 10", width = intWidth, height = intHeight).grid(row = 5,column = c,sticky = E+W)

        label = tk.Label(self, text="Welkom bij NS", font='Verdana 50', fg='#005ca0', bg='#FBC311')
        label.grid(row=1,column=3,columnspan=3)

        path = "nslogo.png"
        img = ImageTk.PhotoImage(Image.open(path))
        panel = Label(self , image=img, bg = '#FBC311', width = 340)
        panel.photo = img
        panel.grid(column=4, row=2)


        button1 = tk.Button(self, text="Actuele reistijden", command=lambda: controller.show_frame("Departure"),bg='#005ca0', fg='white',width=20,height=5)
        button1.grid(row=6, column=3,sticky='nsew')
        button2 = tk.Button(self, text="Go to Page Two", command=lambda: controller.show_frame("PageTwo"),bg='#005ca0', fg='white',width=20,height=5)
        button2.grid(row=6,column=5,sticky='nsew')

class Departure(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        for row in range(7):
            self.grid_rowconfigure(row, weight=1)
        for c in range(7):
            self.grid_columnconfigure(c, weight=1)
        label = tk.Label(self, text="Actuele vertrektijden", font='Verdana 50', fg='#005ca0', bg='#FBC311')
        label.grid(row=0,column=2,columnspan=5)
        button = tk.Button(self, text="Start",command=lambda: controller.show_frame("StartPage"),bg='#005ca0', fg='white',width=20,height=5)
        button.grid(row=2,column=4)


class PageTwo(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        for row in range(7):
            self.grid_rowconfigure(row, weight=1)
        for c in range(7):
            self.grid_columnconfigure(c, weight=1)
        label = tk.Label(self, text="Storingen", font='Verdana 50', fg='#005ca0', bg='#FBC311')
        label.grid(row=0,column=2,columnspan=5)
        button = tk.Button(self, text="Start", command=lambda: controller.show_frame("StartPage"), bg='#005ca0', fg='white',width=20,height=5)
        button.grid(row=2,column=4)


app = SampleApp()

app.mainloop()

But im getting an error:

File "C:/Users/kevin/Desktop/HU/Programming/TICT-ViPROG-15/mini_project/test.py", line 59, in init img = ImageTk.PhotoImage(Image.open(path)) AttributeError: type object 'Image' has no attribute 'open'

I have no idea why this is happening and was hoping someone coul help me with this issue.

Thanks in advance.

Kevin.a
  • 4,094
  • 8
  • 46
  • 82

2 Answers2

2

You have a namespace conflict. Instead of doing...

from PIL import Image,ImageTk

Try doing:

from PIL import ImageTk
from PIL import Image as PilImage

and then, in the line you're getting the error, you'll do:

img = ImageTk.PhotoImage(PilImage.open(path))

I hope that helps. Regards.

Marco Gomez
  • 359
  • 2
  • 6
1

The problem is caused by the way that you import the tkinter module:

from PIL import Image,ImageTk
from tkinter import *

The second import will replace any existing names of variables, classes etc. with those contained in the tkinter module. It just so happens that there is an Image class defined in tkinter (that doesn't have an open() method), so it will replace the one that was already imported from PIL.

>> from tkinter import  *
>>> Image
<class 'tkinter.Image'>

This is a demonstration of why it is preferable not to use import *, although it is common to do so with Tkinter.

One way to fix this is to swap the order of your imports so that PIL.Image replaces tkinter.Image, but that now prevents you from using tkinter.Image if you had wanted to use both in the same namespace.

So, you can import using as to define your own name for items imported from the module:

from PIL import ImageTk, Image as PILImage

and use PILImage instead of Image when you require a PIL.Image.

mhawke
  • 84,695
  • 9
  • 117
  • 138