3

I am attempting for a homework assignment to implement Simon Says in python. I'm trying to do it using the turtle library (a requirement).

However, I've run into a stumbling block in that while I can get the screen to register click events (currently just printing the x,y coordinates) I can't get it to wait for a click event.

Specifically what I'm planning on doing is having areas on the screen that when they click within that location it is considered as if they had clicked a button. Screen clears and game does whatever.

However, in experiments in trying to get a working 'button' all that it does is set it so it prints the x,y coordinates but the rest of the program finishes. Didn't wait for the user to click anything. I tried a blocking method of...

while clicked == False:
    pass

or

while clicked == False:
    time.sleep(1)

but both methods hangs the program until I manually interrupt and then it'll print the clicks.

Am I missing an option somewhere?

user2309351
  • 47
  • 1
  • 1
  • 6
  • are you not checking for a button press? – PurityLake Nov 17 '13 at 19:39
  • Turtle doesn't have buttons as far as I know. I'm trying to mimic the effect. If there is a button for turtle I would love to know of it. – user2309351 Nov 17 '13 at 20:47
  • I have never used turtles but there is a method `turtle.onrelease(fun, btn=1, add=None)` i'm pretty sure if you use this you can make a button, just check the x, y co-ords? – PurityLake Nov 17 '13 at 21:02
  • That calls the attached function yeah. But the program doesn't wait. Say I have 2 buttons. Program is expecting me to push one or the other. I do 'turtle.onrelease', 'turtle.onclick', or whatever it'll call the function but the program would have already crashed as the expected variables are null because it set it to use that function and then continued on. – user2309351 Nov 17 '13 at 21:13
  • ah so it is a threading problem? sorry if i am interpreting this wrong – PurityLake Nov 18 '13 at 00:43
  • This page might help with the general "button problem" of Python turtles: https://repl.it/@ssinha_tesp/Turtle-Buttons#main.py – tonethar May 28 '20 at 01:49
  • This sounds like an [xy problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem/233676#233676). You can just chain the next piece of code from the click handler callback as normal, I'd think. Another approach more suitable for a complex, realtime app is to run a loop with `ontimer` and poll a flag that a handler might flip to determine when the condition is right to move on to another function, as illustrated in different context [here](https://stackoverflow.com/questions/47879608/70979967#70979967). Beyond that, the answer would be very use-case dependent. – ggorlen Feb 05 '22 at 20:21
  • Does this answer your question? [How can I create a button in turtle?](https://stackoverflow.com/questions/59902849/how-can-i-create-a-button-in-turtle) – ggorlen Feb 05 '22 at 20:22

3 Answers3

0

Turtles don´t have buttons, but they do have callbacks for clicks. Furthermore, you should use onclick for Screen to detect general clicks and onclick for turtle to detect clicking in turtles. You can, for example, make a 4 BIG turtles with different colors by using a dynamic shape.

Also, turtle is based on Tk, so you must be aware of things like mainloop()

The following program give some hints for Python 2.7.5.

import turtle as t
from random import randint

class MyTurtle(t.Turtle) :

    def __init__(self,**args) :
        t.Turtle.__init__(self,**args)

    def mygoto(self,x,y) :
        t1.goto(x,y)
        print x,y

    def randonics(self,x,y) :
        self.left(randint(90,270))

def minegoto(x,y) :
    print x,y
    t1.goto(x,y)

wt=t.Screen()
t1=MyTurtle()
wt.register_shape("big",((0,0),(30,0),(30,30),(0,30)))
t1.shape("big")
wt.onclick(t1.mygoto,btn=1)
wt.onclick(minegoto,btn=2)
t1.onclick(t1.randonics,btn=3)
t1.goto(100,100)

t.mainloop()
Andrey Chaschev
  • 16,160
  • 5
  • 51
  • 68
Xexeo
  • 302
  • 1
  • 12
  • This is what I've been able to do. However, I want the program to stop executing, hold until a click event has registered, find out where that click was, and do some code dependent on where the user clicked. Effectively a button. This might need threading as someone has suggested above but there is only one path through the program (a user defined path) but just one. Unless t.mainloop() does something special I'm missing? – user2309351 Nov 20 '13 at 01:38
  • You can make the function registered with onclick() test the x,y position. If it is inside some region you do whatever you must. I don´t see the difference between what you want to do and what this code does, the modification of turtle position is just an example, you can do anything when a click is captured by onclick(), even start a thread if you really need it. – Xexeo Nov 22 '13 at 22:36
0

So after extensive search there isn't necessarily a way pause execution of the code in python while using turtle to wait for some click event. Maybe in Tk I could do that but not in turtle.

However, there is a way to get around that. As an example. A method sets up the fake button on the screen, sets the click event, and terminates. The click event when clicked calls the next method needed for execution. So until the button is clicked the actual code isn't doing anything but remains in memory for use.

So more specifically. 1. Create a 'button'. 2. Have your program behave normally until it needs to wait for a click event. 3. Set up the on screen click (or on turtle) in such a way when the 'button' is clicked the next part of the code is run.

Special note. The code in question can't depend on waiting for a click event for later on in code. Instead, the click causes the next part of the execution of your code.

user2309351
  • 47
  • 1
  • 1
  • 6
0

You can make the function registered with onclick() test the x,y position. If it is inside some region you do whatever you must.

I don´t see the difference between what you want to do and what this code does, the modification of turtle position is just an example, you can do anything when a click is captured by onclick(), even start a thread if you really need it (using Creating Threads in python)

import turtle as t
from random import randint
from threading import Thread
from time import sleep

def threaded_function(arg,t1):
    for i in range(arg):
        print "running",i
        sleep(1)
        t1.forward(i*10)



def minegoto(x,y) :
    print x,y
    t1.goto(x,y)
    thread = Thread(target = threaded_function, args = (10,t1 ))
    thread.start()
    thread.join()
    print "thread finished...exiting"

wt=t.Screen()
t1=t.Turtle()
wt.register_shape("big",((0,0),(30,0),(30,30),(0,30)))
t1.shape("big")
wt.onclick(minegoto,btn=1)
t1.goto(100,100)

t.mainloop()
Community
  • 1
  • 1
Xexeo
  • 302
  • 1
  • 12