-1

I'm using TkInter to write a GUI that will contain an image and a few buttons in a panel next to the image.

I started by writing a script that would allow me to visualize an image, and it works just fine:

#!/usr/bin/python
# -*- coding: iso-8859-1 -*-

import Tkinter
from PIL import Image, ImageTk

window = Tkinter.Tk()
window.title("Test GUI")
window.geometry("640x478")
window.configure(background='grey')

window.grid()

img = ImageTk.PhotoImage(Image.open('./test.jpg'))

canvas = Tkinter.Canvas(window, width=640, height=478, bg='white')
canvas.create_image(0,0,anchor='nw',image=img)

canvas.grid(column=0,row=0)

window.mainloop()

enter image description here

I then tried to rewrite the above code as a class, to implement some event-handling functions. However, the same exact code written in the class initialization function will not visualize the image.

#!/usr/bin/python
# -*- coding: iso-8859-1 -*-

import Tkinter
from PIL import Image, ImageTk

class showImageGUI(Tkinter.Tk):
    def __init__(self,parent):
        Tkinter.Tk.__init__(self,parent)
        self.parent = parent
        self.initialize()

    def initialize(self):

        # the grid layout manager is a simple grid 
        # where you put your widgets
        self.grid()

        img = ImageTk.PhotoImage(Image.open('./test.jpg'))

        canvas = Tkinter.Canvas(self, width=640, height=478, bg='white')
        canvas.create_image(0,0,anchor='nw',image=img)

        canvas.grid(column=0,row=0)

if __name__ == "__main__":
    app = showImageGUI(None)
    app.title('Test GUI')
    # event-driven programming: the program will 
    # loop forever doing nothing but wait for events
    # and only react when it receives an event
    app.mainloop()

enter image description here

The only difference between the two is:

  • In the script implementation I assign the parent of the canvas widget to be the whole window.
  • In the class implementation I assign the parent of the canvas widget to be the self variable for the whole app.

Can someone please explain me why is this breaking the code / how to solve it?

Matteo
  • 7,924
  • 24
  • 84
  • 129
  • As I always say, even though a lot of people disagree with me, I would never recommend anyone to use TKInter to design a GUI. It's very unfamiliar with design precepts. There is no intuitiveness. There are much better GUI frameworks than _that_. –  Sep 19 '15 at 21:16
  • @J.C.Rocamonde - Thanks for your comment. Is there any recommendation you have among all [these](https://wiki.python.org/moin/GuiProgramming)? – Matteo Sep 19 '15 at 21:42
  • I have only tried few, since I don't usually work with the front end part of code. However, from all I've tried, the Kivy framework is a very nice, updated, well-looking, cross-platform framework, which even has its own language similar to CSS which you may add in a separate file or inside the Python file itself, that structures the design. –  Sep 19 '15 at 21:51
  • TKInter is very popular because was one of the first, efficient UI Python framework, which event got assembled into the python code itself, that considerably stimulated its usage. But it contains very serious bugs and it didn't update itself, by which other frameworks gain ground. –  Sep 19 '15 at 21:58
  • @J.C.Rocamonde - Thanks! Great answer. – Matteo Sep 19 '15 at 22:10

1 Answers1

1

There's a bug in Tkinter that causes images to disappear if there is no external reference to them, even though they should be bound into the Canvas widget somehow. I'm probably not explaining this well, because I've never taken the trouble to really research what is going on. I believe it is explained somewhere on effbot.org.

In any event, change the line

img = ImageTk.PhotoImage(Image.open('./test.jpg'))

to

img = self.img = ImageTk.PhotoImage(Image.open('./test.jpg'))

and I think it will work for you. It works for me.

saulspatz
  • 5,011
  • 5
  • 36
  • 47