PLEASE HELP--Button images refuse to show.

B

Barrett

I have been fighting the same bug for weeks now with zero success: I
am trying to get images to come up on my buttons, but they are way too
small. Regardless of whether I used my old Python 2.5.1 or now 2.6.5,
the following code:

====================
'''Minesweeper.'''

from Tkinter import *
#from PIL import Image
import Tkinter as tk
#import PIL as pil
import random
#import glob, os

BEGINNER = 1
INTERMEDIATE = 2
EXPERT = 3

OFFSET = 2

BUTTON_SIZE = 2

class Board(Frame, object):
def __init__(self, master, difficulty, photo):
Frame.__init__(self, master)
if difficulty == BEGINNER:
self.x = 9
self.y = 9
self.mines = 10
elif difficulty == INTERMEDIATE:
self.x = 16
self.y = 16
self.mines = 40
elif difficulty == EXPERT:
self.x = 30
self.y = 16
self.mines = 99

self.grid()
self.photo = photo
self.create_widgets()

def create_widgets(self):
#Create the grid.
self.square = []
self.isAMine = []
self.selected = []
for i in range(self.x):
squareColumn = []
mineColumn = []
selectedColumn = []
for j in range(self.y):
squareColumn.append(Button(self, width = 3, height =
2,\
padx = -1, pady = -1))
squareColumn[j].grid(row = j + OFFSET, column = i)
mineColumn.append(False)
selectedColumn.append(False)
self.square.append(squareColumn)
self.isAMine.append(mineColumn)
self.selected.append(selectedColumn)

#Plant the mines.
print 'Dimensions:', self.x, self.y
for i in range(self.mines):
mineSquare = random.randrange(self.x * self.y)
mine_y = mineSquare / self.x
mine_x = mineSquare % self.x
self.isAMine[mine_x][mine_y] = True
self.square[mine_x][mine_y]['text'] = 'X' #temp line;
shows mines
#photo = tk.PhotoImage(file="1.gif")
#self.square[mine_x][mine_y]['image'] = photo #temp line;
shows mines


for i in range(self.y):
for j in range(self.x):
self.square[j]['command'] = lambda x=j, y=i:
self.hit(x, y)

#Runs when a button (square) is clicked.
def hit(self, x, y):
self.selected[x][y] = True
self.square[x][y].config(relief=SUNKEN)

#print x, y
if self.isAMine[x][y]:
print 'Mine found. Location:', x, y
else:
#Look at all eight neighbors and see if they are mines.
#x>0, etc. avoid looking off the edge of the map.
adjMines = 0
if (x > 0 and y > 0) and self.isAMine[x-1][y-1]: #NW
adjMines+=1
if y > 0 and self.isAMine[x][y-1]: #N
adjMines+=1
if (x < self.x-1 and y > 0) and self.isAMine[x+1][y-1]:
#NE
adjMines+=1
if x > 0 and self.isAMine[x-1][y]: #W
adjMines+=1
if x < self.x-1 and self.isAMine[x+1][y]: #E
adjMines+=1
if (x > 0 and y < self.y-1) and self.isAMine[x-1][y+1]:
#SW
adjMines+=1
if y < self.y-1 and self.isAMine[x][y+1]: #S
adjMines+=1
if (x < self.x-1 and y < self.y-1) and\
self.isAMine[x+1][y+1]: #SE
adjMines+=1

if adjMines != 0 and adjMines < 3:
self.square[x][y]['text'] = ''
self.square[x][y]['image'] = self.photo[adjMines]

elif adjMines>0: #temp line until the pix are ready
self.square[x][y]['text'] = adjMines

else: #adjMines == 0
#If none of the adjacent squares have mines, it is
safe to hit
#them all. Just like the official game, this game
does
#precisely that.
if (x > 0 and y > 0) and not self.selected[x-1][y-1]:
Board.hit(self, x-1, y-1) #NW
if y > 0 and not self.selected[x][y-1]: #N
Board.hit(self, x, y-1)
if (x < self.x-1 and y > 0) and not self.selected[x+1]
[y-1]: #NE
Board.hit(self, x+1, y-1)
if x > 0 and not self.selected[x-1][y]: #W
Board.hit(self, x-1, y)
if x < self.x-1 and not self.selected[x+1][y]: #E
Board.hit(self, x+1, y)
if (x > 0 and y < self.y-1) and not self.selected[x-1]
[y+1]: #SW
Board.hit(self, x-1, y+1)
if y < self.y-1 and not self.selected[x][y+1]: #S
Board.hit(self, x, y+1)
if (x < self.x-1 and y < self.y-1) and\
not self.selected[x+1][y+1]:
Board.hit(self, x+1, y+1) #SE

self.square[x][y]['command'] = ''

def main():
root = Tk()
root.title('Minesweeper')
root.geometry('450x300')
diff = int(raw_input( 'Select your difficulty level: '))
try:
photo = []
photo.append(None)
photo.append(tk.PhotoImage(file="1.gif"))
photo.append(tk.PhotoImage(file="2.gif"))
#photo[1] = photo[1].resize((15, 15))
except (IOError):
print 'File missing.'
else:
theBoard = Board(root, diff, photo)

root.mainloop()

main()
====================

Results in the following:

http://img194.yfrog.com/img194/237/weirdness3.jpg

("3" and above, I have not coded the pix for. I want to get the "1"
and "2" right before proceeding.)

I am completely at wit's end. I have tried using PIL, I have tried
resizing the buttons, and zooming the images, and saving the images
as .gif's and .jpeg's and .bmp's and you name it. Absolutely nothing
is working. I have a major assignment due TOMORROW and absolutely MUST
figure this out. Someone please show me what the heck I am doing wrong
and what I can do to fix it.
 
G

Gabriel Genellina

I have been fighting the same bug for weeks now with zero success: I
am trying to get images to come up on my buttons, but they are way too
small. Regardless of whether I used my old Python 2.5.1 or now 2.6.5,
the following code:

[... too much code ...]

Results in the following:

http://img194.yfrog.com/img194/237/weirdness3.jpg

("3" and above, I have not coded the pix for. I want to get the "1"
and "2" right before proceeding.)

I am completely at wit's end. I have tried using PIL, I have tried
resizing the buttons, and zooming the images, and saving the images
as .gif's and .jpeg's and .bmp's and you name it. Absolutely nothing
is working. I have a major assignment due TOMORROW and absolutely MUST
figure this out. Someone please show me what the heck I am doing wrong
and what I can do to fix it.

I'm afraid this is coming late for your assignment then. For the next time:

- Try to isolate the problem. Start with your current, full program, and
strip down sections (one at a time) and see whether the problem is still
present or not. Eventually, you'll get working code (so you know the last
removed section was the culprit) or it becomes so small that you cannot
simplify it further.
(You posted a very long program, most of it irrelevant for this question)

- Explain how to reproduce the problem, what you got, and what you
expected to get. (You posted what you got, but not what you expected. I
had to *imagine* that those funny squares were supposed to contain an
image).

This is a heavily stripped down version of your program that still shows
the problem:

<code>
import Tkinter

def callback():
b['image'] = image
b['text'] = ''

root = Tkinter.Tk()
image = Tkinter.PhotoImage(file="1.gif")
b = Tkinter.Button(root, width=3, height=2, command=callback)
b['text'] = 'X'
b.pack()
root.mainloop()
</code>

If you remove the 'width' and 'height' specifications, it works fine. Now
look at the documentation, from http://effbot.org/tkinterbook/button.htm :

"height= The height of the button. If the button displays text, the size
is given in text units. If the button displays an image, the size is given
in pixels (or screen units). If the size is omitted, it is calculated
based on the button contents. (height/Height)

width= The width of the button. If the button displays text, the size is
given in text units. If the button displays an image, the size is given in
pixels (or screen units). If the size is omitted, or zero, it is
calculated based on the button contents. (width/Width)"

Initially the button contains text, so width=3 and height=2 are in
character units. When you set an image, the same values are interpreted in
pixels instead.

Replace the callback function with this one, or some variant:

def callback():
b.config(image=image, text='',
width=image.width(),
height=image.height())

(btw, notice usage of config() to set widget attributes, and implicit line
continuation instead of \ )
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top