0

I'm trying to create a while loop which will check the entry widgets e1 and e2 for the correct answer from a list and if it is correct it will randomly choose another image to place onto the canvas and if it is wrong then it will print the text incorrect onto the screen. The while loop I currently have isn't giving me any errors but it is hanging the program and I can't figure out what is causing the problem.

EDIT: I'm now able to get the gamescreen to load after putting this line at the end canvas.mainloop() however the if statements within the while loop are not working, I'm also experiencing a new error which doesn't affect the program which I added at the bottom.

Here is the updated while loop:

def gamescreen():
    imagelist = ["1.gif","2.gif","3.gif","4.gif","5.gif","6.gif","7.gif","8.gif","9.gif","10.gif","11.gif","12.gif","13.gif","14.gif","15.gif","16.gif","17.gif","18.gif","19.gif","20.gif","21.gif","22.gif","23.gif","24.gif","25.gif","26.gif","27.gif","28.gif","29.gif","30.gif","31.gif","32.gif","33.gif","34.gif","35.gif","36.gif","37.gif","38.gif","39.gif","40.gif","41.gif","42.gif","43.gif","44.gif","45.gif","46.gif","47.gif","48.gif","49.gif","50.gif"]
    answerlistx = [-1, -3, 3, 4, -7, 8, 9, 10, -10, 2, -7, 7, -1, -5, -6, -9, -7, 10, -4, 8, 1, -8, -10, -1, -3, -7, -3, 7, 3, -4, 1, -8, -4, 9, -5, -10, 10, 2, 2, -10, 4, 9, -3, 6, 10, -6, 4, 9, -10, -10]
    answerlisty = [3, -6, -5, 3, -2, 4, -4, -3, 4, -6, 1, 2, 2, 3, 2, -1, -5, 1, -3, 1, -2, -2, -5, -3, -2, -6, -3, 6, 2, 0, -5, 6, -4, 4, 1, -6, 0, -6, 5, 2, 4, -4, -2, 0, -3, -6, -4, 1, -3, 1]

    canvas.bind("<Button-1>", buttonclick_gamescreen)
    canvas.pack(expand = YES, fill = BOTH)
    photo = PhotoImage(file="gamescreen.gif")
    canvas.create_image(1, 1, image = photo, anchor = NW)
    e1 = Entry(canvas, width = 11)
    e2 = Entry(canvas, width = 11)
    canvas.create_window(390, 501, window=e1, anchor = NW)
    canvas.create_window(551, 501, window=e2, anchor = NW)
    canvas.after(1, countdowntimer)
    while cdtimer > 0:
        print("start of while loop")
        randomimage = random.randrange(0,49+1)
        game = PhotoImage(file=imagelist[randomimage])
        images = canvas.create_image(30, 65, image = game, anchor = NW)
        if pressed == 8 and e1 == answerlistx[randomimage] and e2 == answerlisty[randomimage]:
            print("correct")
            canvas.delete(images)
            randomimage = random.randrange(0,49+1)
            scorecounter = scorecounter + 1
            game = PhotoImage(file=imagelist[randomimage])
            images = canvas.create_image(30, 65, image = game, anchor = NW)
            e1.delete(0, END)   
            e2.delete(0, END)
        elif pressed == 8 and e1 != answerlistx[randomimage] or pressed == 8 and e2 != answerlisty[randomimage]:
            print("incorrect")
            wronganswer = canvas.create_text(400, 200, text="Incorrect", font="Ubuntu 29 bold", fill='red', anchor=NW)
            e1.delete(0, END)   
            e2.delete(0, END)
            canvas.after(1500,(canvas.delete(wronganswer))) 
        canvas.mainloop()

This is where the pressed == 8 value comes from:

def buttonclick_gamescreen(event):
    global pressed
    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 

    if pressed == 7 :
        window.destroy()
    if pressed == 8:
        print("next button")

This new error occurs when I press the exit button in the gamescreen() or in the scorescreen()

start of while loop
start of while loop
Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python3.2/tkinter/__init__.py", line 1402, in __call__
    return self.func(*args)
  File "/home/ppppwn3d/workspace/Python/JailBreakBob/JailBreakBob.py", line 114, in buttonclick_mainscreen
    gamescreen()
  File "/home/ppppwn3d/workspace/Python/JailBreakBob/JailBreakBob.py", line 60, in gamescreen
    game = PhotoImage(file=imagelist[randomimage])
  File "/usr/lib/python3.2/tkinter/__init__.py", line 3231, in __init__
    Image.__init__(self, 'photo', name, cnf, master, **kw)
  File "/usr/lib/python3.2/tkinter/__init__.py", line 3172, in __init__
    raise RuntimeError('Too early to create image')
RuntimeError: Too early to create image

Would be really helpful if someone could point me in the right direction. PS: This is the full code incase I haven't provided enough information Link to full code on pastebin

Thanks in advance!

ThatsNotMyName
  • 572
  • 2
  • 8
  • 24

1 Answers1

1

Your while loop is not giving the main loop a chance to run. For this reason, once buttonclick_mainscreen calls gamescreen, pressed remains 1 and never changes its value.

Any callback called from the event loop must immediately return to the event loop, otherwise the program becomes unresponsive. Instead of staying in the while loop, simply return from gamescreen and do the rest of the work from callbacks that process user events (canvas.bind) and timeouts (canvas.after). Each iteration of the current loop will be one invocation of the callback.

It is at first confusing to rewrite algorithms in this way, but that's how event loops work.

user4815162342
  • 141,790
  • 18
  • 296
  • 355
  • Hey there thanks for the answer but I'm a bit confused about your statement "Each iteration of the current loop must be a executed as a call of a new callback function." I can't wrap my head around that, is there any chance you could explain it a bit more or show it with example code? Google wasn't much help :/ Thanks for your time. – ThatsNotMyName Jul 16 '13 at 06:10
  • @ThatsNotMyName I've updated the second paragraph with a more detailed description. If you still don't understand it, you might want to pick up a good book on Tkinter to explain the basic concepts. – user4815162342 Jul 16 '13 at 06:31
  • Also, [the accepted answer](http://stackoverflow.com/a/17538528/1600898) to one of your previous questions already contains an example that shows how to do what I describe here. – user4815162342 Jul 16 '13 at 13:32