0

I am searching for a way to generate buttons with pictures for a little game. I am using Tkinter and a Grid layout in two ways but only one of them worked.

Here is the example code of the first (hardcoded) way to generate the Button with a picture:

currentImage=PhotoImage(file="Pictures//greenopen1s.gif")
currentImage = currentImage.subsample(x = "2", y = "2")
b2 = Button(root, image=currentImage)
b2.grid(column = 0, row = 1)

root.mainloop()

and here is the second generic way to generate the button with an image opened according to the argumented card:

b1 = Button(root, image=getImage(visibleCards[0])) 
b1.grid(column = 0, row = 0)

root.mainloop()

def getImage(card):
 currentPath = "Pictures//"
 currentColor = card.color
 currentPath = currentPath + currentColor
 currentShading = card.shading
 currentPath = currentPath + currentShading
 currentNumber = card.number
 currentPath = currentPath + currentNumber
 currentPath = currentPath + card.symbol
 currentPath = currentPath + ".gif"

 currentImage=PhotoImage(file=currentPath)
 currentImage = currentImage.subsample(x = "2", y = "2")

 return currentImage

The image algorithm to load the PhotoImage works correctly and the .gif files are in the correct location. I would like to know the difference between these two ways of getting the image.

Thank you very much

Reallyor
  • 37
  • 9
  • Not really sure what you are asking --- the differences are pretty apparent. One is a custom function you have created (called `getImage`) and the other (first technique) just calls the `PhotoImage()` class directly. Both have the same result, correct? Can you clarify what the "problem" is? Are you asking for opinions on which technique is better? /confused – Justin Carroll Aug 13 '14 at 22:41
  • You should debug it by printing out "currentPath" just before the call to PhotoImage and make sure that it is a valid path to an existing file. – OldGeeksGuide Aug 13 '14 at 22:45
  • And not so much a comment on the second method, but I'd look into [string methods](https://docs.python.org/2/library/string.html#format-string-syntax). That can dramatically shore up all that string concatting you are doing. – Justin Carroll Aug 13 '14 at 22:46
  • Thank you very much for your comments. The purpose of my question is to get information about the mistake i am doing in the second technique. The second technique doesnt work and i do not know the reason for this misbehaviour. – Reallyor Aug 14 '14 at 08:13

1 Answers1

2

PhotoImage has trouble with garbage collection, so whatever variable gets set as a PhotoImage object can't get garbage collected. It's kind of odd and I'm not sure why it works that way, honestly.


Try something like this:

myImage = getImage(visibleCards[0])
b1 = Button(root, image=myImage) 
b1.grid(column = 0, row = 0)

root.mainloop()

def getImage(card):
    currentPath = "Pictures//"
    currentColor = card.color
    currentPath = currentPath + currentColor
    currentShading = card.shading
    currentPath = currentPath + currentShading
    currentNumber = card.number
    currentPath = currentPath + currentNumber
    currentPath = currentPath + card.symbol
    currentPath = currentPath + ".gif"

    currentImage=PhotoImage(file=currentPath)
    currentImage = currentImage.subsample(x = "2", y = "2")

    return currentImage
dpwilson
  • 997
  • 9
  • 19
  • If you think your explanation is bad, don't explain it. Instead, rewrite it so that it doesn't need explanation. One clear answer is worth more than a bad answer with a "Edit" section. – Bryan Oakley Aug 13 '14 at 23:00
  • Thanks @BryanOakley, I updated it as per your comment. I'm still trying to get a handle on this site! – dpwilson Aug 13 '14 at 23:08
  • 1
    Your answer isn't quite correct. It's not that the veriable must be global per se, it's simply that it can't get garbage collected. Storing it as an attribute to an object works, for example, without making it global. – Bryan Oakley Aug 13 '14 at 23:40
  • Very true. I'm glad there are people like you around to correct me. – dpwilson Aug 14 '14 at 00:00