I'm trying to code the game of minesweeper. For some reason, the image won't display properly--and it isn't a case of a missing file, b/c I have a try-except code snippet that is set to print out an error message should this occur, and that isn't happening. So either it's misreading the image or just not displaying it properly.

Here is the relevant code (obviously this is a work-in-progress):

if adjMines>0:
                self.square[x][y]['text'] = adjMines
                try:
                    image = []
                    image.append(PhotoImage(file='1.gif'))
                    image.append(PhotoImage(file='2.gif'))
                    self.square[x][y]['text'] = adjMines
                except (IOError):
                    print 'File missing.'
                else:
                    if adjMines == 1:
                        self.square[x][y]['text'] = ''
                        self.square[x][y]['image'] = image[0]
                    elif adjMines == 2:
                        self.square[x][y]['text'] = ''
                        self.square[x][y]['image'] = image[1]

BTW, the text thing was what I had going on in the alpha version of the program: It would change the button's text to the appropriate number.

Here is what it looks like:

(And yes, I know the square sizes are goofy. I'm still in the development phase of this program. ETA: On the same token, the 'X' is a mine.)

More importantly, why am I just getting these little gray squares?

Dani AI

Generated

Most likely cause: the PhotoImage objects are being created as local variables and then garbage-collected, leaving Tk with a “dead” image (the little gray box). Create the image objects once and keep a persistent Python reference (either on your board object or attached to each button). That also fixes the “image jumps to the most-recently-updated square” symptom.

A minimal pattern that works reliably (create images once, then assign and keep a reference on the widget):

# e.g. in your board-class __init__
self.number_images = [
    PhotoImage(file='1.gif'),
    PhotoImage(file='2.gif'),
    # ...
]

# when revealing a square
btn = self.square[x][y]
img = self.number_images[adjMines-1]
btn.config(image=img, text='')
btn.image = img   # keep a Python-level reference so it isn't GC'd

Other practical checks and tips:

  • Make sure you load the PhotoImage objects after creating the Tk root (calling PhotoImage before Tk() can misbehave).
  • Confirm the file paths and formats; Tkinter PhotoImage supports GIF/PNG—use Pillow (ImageTk.PhotoImage) if you need JPEG or other formats.
  • If the image looks “squashed,” check how the button was created: Button width/height are in text units, not pixels, and can change layout; try a single test program (one button + one image) to isolate layout vs. image problems.
  • Don’t recreate the same PhotoImage for every reveal inside the reveal routine — create once and reuse.

This directly addresses the symptoms you described: the update() suggestion from won't prevent GC, and the behavior you saw (squashed preview, image moving to the next revealed tile) is exactly what happens when image references are transient. Storing images in self and also on each button (for extra safety) is the simplest robust fix.

Recommended Answers

All 4 Replies

You might need to use self.update() or self.square.update()

Would be nice to know what self.square is.

You might need to use self.update() or self.square.update()

Would be nice to know what self.square is.

"square" is a two-dimensional list of buttons.

I inserted the following two lines:

self.update()
self.square[x][y].update()

at the end of the above section. No change. But strangely, when I insert this line:

self.square.update()

I get an error, which is to be expected since square is a list. But I can see a squashed image in the little gray square! And when another 1- or 2-space is selected, the image moves to that square.

Is it simply a matter of the size of the contained image square?

Someone please help me. I need this taken care of ASAP.

I'm gonna try out PIL.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.