Jay Gattuso
Jay Gattuso

Reputation: 4130

Python Tkinker - showing a jpg as a class method not working

I'm trying to show a jpg image as background for a GUI thing I'm building.

I can get it to work in a single method:

from Tkinter import *
from PIL import Image, ImageTk

class MakeGUI(object):
    master = None
    w = None

    def __init__(self):
        self.canvasSizeY = 400 #height
        self.canvasSizeX = 640 #width

    def setupCanvas(self):
        """
        preps the canvas for drawing.
        """
        self.master = Tk()
        self.w = Canvas(self.master, width=self.canvasSizeX, height=self.canvasSizeY)
        self.w.config(bg='white')
        image = Image.open("background.jpg")
        photo = ImageTk.PhotoImage(image)
        self.w.create_image(0,0, image=photo, anchor=NW)
        self.w.pack()
        mainloop()

def main():
    makeGUI = MakeGUI()
    makeGUI.setupCanvas()

if __name__ == '__main__':
    main()

But when I try and make the canvas in one method, and show the canvas in another, it doesn't show the jpg (when I've been testing, I've created and shown & text and rectangles using this approach):

from Tkinter import *
from PIL import Image, ImageTk

class MakeGUI(object):
    master = None
    w = None

    def __init__(self):
        self.canvasSizeY = 400 #height
        self.canvasSizeX = 640 #width

    def setupCanvas(self):
        """
        preps the canvas for drawing.
        """
        self.master = Tk()
        self.w = Canvas(self.master, width=self.canvasSizeX, height=self.canvasSizeY)
        self.w.config(bg='white')
        image = Image.open("background.jpg")
        photo = ImageTk.PhotoImage(image)
        self.w.create_image(0,0, image=photo, anchor=NW)

    def showImage(self):
        """
       pushes the image to the screen
       """
        self.w.pack()
        self.w.mainloop()

def main():
    makeGUI = MakeGUI()
    makeGUI.setupCanvas()

if __name__ == '__main__':
    main()

I want to use the GUI dynamically to show some text as I work through some editing, so I'm interested to understand what I've got wrong before I get too far into the build in case its a showstopper...

Upvotes: 1

Views: 550

Answers (1)

Bryan Oakley
Bryan Oakley

Reputation: 386342

The most obvious problem is that in the second case you are never calling showImage. Even after you do call that function, your image probably won't show up. Images will be garbage-collected if there isn't a reference to them. It may seem like there's a reference because you're adding it to a canvas, but that isn't enough.

You'll need to do something like:

self.photo = ImageTk.PhotoImage(image)

Finally, I recommend that you take the call to mainloop out of showImage. mainloop must always be called exactly once, so most typically it is the last line of code in your program, or the last line of code in your main function.

A more common way to make a Tkinter application is to subclass either the Tk object or a Frame object, rather than having your main application be a generic object. For example:

class MyApp(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        ...
        self.setupCanvas(...)
        ...
if __name__ == "__main__":
    app = MyApp()
    app.mainloop()

Upvotes: 2

Related Questions