0

I have a statement inside a while statement that is supposed to draw an image onto the canvas but it doesn't happen and I don't know why as it doesn't show any errors.

def buttonclick_gamescreen(event):
    global scorecounter
    global pressed
    global randomimage
    global images
    pressed = ""

    if event.x >853 and event.x <957 and event.y > 8 and event.y < 56 : pressed = 7 
    if event.x >666 and event.x <947 and event.y > 491 and event.y < 534 : pressed = 8
    while pressed == 8 :
        entryx = e1.get()
        entryy = e2.get()
        answerx = answerlistx[randomimage]
        answery = answerlisty[randomimage]
        print("The answer to X is", answerx, "You entered", entryx,"The answer to Y is", answery, "You entered ", entryy)
        if entryx == answerx and entryy == answery:
            print("correct")
            canvas.delete(images)
            randomimage = random.randrange(0,49+1)
            scorecounter = scorecounter + 1
            print("You score is now", scorecounter, "New random number is", randomimage)
            game = PhotoImage(file=imagelist[randomimage])
            images = canvas.create_image(30, 65, image = game, anchor = NW)
            e1.delete(0, END)   
            e2.delete(0, END)
            pressed = ''
        else:
            print("incorrect")
            e1.delete(0, END)   
            e2.delete(0, END)
            pressed = ''

The line images = canvas.create_image(30, 65, image = game, anchor = NW) should work as it worked in another case for me.

Here's a link to the rest of the code since I don't want to make this question too long and messy, which shows where the canvas is drawn. http://pastebin.com/RxmPDUAD From my understanding right now I'll have to create a class and call the functions from there for this to work? EDIT: Having trouble still as I've tried using global variables and classes with no luck.

It's not a problem with the random number as I printed it just before the line the image is supposed to print from just incase it didn't work but it does. What am I doing wrong?

7
  • Are you entering the mainloop? Nothing tk-wise will happen until you do. All tasks are essentially queued up, the mainloop will run through the queue of tasks and perform any actions, process events etc. Commented Jul 21, 2013 at 9:22
  • I'm not entirely sure what that means, but I'm going to guess it's not, so I'll have to go look up that, thanks for the comment. Commented Jul 21, 2013 at 9:41
  • I mean are you calling canvas.mainloop() somewhere? (you haven't in the code you provided, but I think that's not all of the code as there are symbols used in there which aren't defined.) Commented Jul 21, 2013 at 9:56
  • @GP89 It's in the very last line of the second code block, but you are right: The code is not complete, and thus hard to reproduce the problem. Where and how is the canvas created? Commented Jul 21, 2013 at 10:04
  • 1
    It is highly unusual to have to compare the coordinates of the event to some magic numbers. Are you aware that you're able to create events that only fire if someone clicks on a specific button or canvas item so that you don't have to guess which widget was clicked on? Commented Jul 23, 2013 at 2:18

1 Answer 1

3

Without having actually tested your code, I'm pretty sure the problem is that your PhotoImage objects are being garbage-collected when you exit the method. For some weird reason, just passing them to canvas.create_image won't prevent this. Try to make them global:

global game
game = PhotoImage(file=imagelist[randomimage])
images = canvas.create_image(30, 65, image = game, anchor = NW)

Also see this, this and this related questions/answers.

Some more pointers:

  • conditions like event.x >853 and event.x <957 can be written as 853 < event.x < 957
  • you can define your imagelist as ["%d.gif" % (i+1) for i in range(50)]
  • the after method takes a time in milliseconds, so I guess this should be after(1000, ...)
  • in it's current state, the while pressed == 8: loop seems not to make much sense, since pressed is set to '' after one iteration anyway
  • finally, I'd recommend defining a custom class GameFrame(Frame) and putting all this stuff in that class, instead of making everything global; in this case, you can use the self keyword to bind your PhotoImage to the Frame to prevent it from being garbage-collected
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for your answer, will check them out now.
I'm currently trying to learn how to create a class now and the those if event things are buttons (Not the most efficient way I know.)
Sorry for the late reply been sick, but I have tried using a class and also making it global without any success, I looked up garbage collection and tried turning it off with gc.disable() without much luck either.
@ThatsNotMyName I've just now come to reproduce your problem (not easy when you don't have the images and do not know where to click...), but it seems to work when I make the game image global. -- see my edit. Still, I would recommend re-posting this question (or a variant thereof) on Codereview to receive further input on how to improve your code.
oh hmm, that works, thanks very much for this, I can now start working on making the code more efficient, thanks for your help!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.