Gondamar
Gondamar

Reputation: 11

How can I use value of onscreenclick(func) event outside func?

Using Turtle, I want to be able to make a variable that contains the position on the screen that the user clicked.

I've found that it's possible to print the location of a click using the following code:

import turtle

def find_click_pos(x, y):
    print('{0}, {1}'.format(x, y))

def main():
    turtle.onscreenclick(find_click_pos)

main()

turtle.mainloop()

The problem with this is that the x, y co-ordinates are only defined in the find_click_pos function, and as far as I know there's no way to use them elsewhere in the function without using global variables (which I'd like to avoid at all costs).

Is there any way to get the value of .onscreenclick() without sending it to a function? Is there any other function of turtle that does what I want that I'm missing?

Upvotes: 1

Views: 317

Answers (2)

cdlane
cdlane

Reputation: 41905

This seems the wrong thing to do. I like @Blckknght's object-based solution (+1) but you'd just be substituting a global variable containing an object instance for a global variable containg a position.

If you really want to do the wrong thing, and avoid a global variable, you might as well do it the wrong way -- and what can be more wrong than a dangerous default value:

import turtle

def get_click_position(x=None, y=None, stash=[0, 0]):  # dangerous default value
    if x != None != y:
        stash[0:] = (x, y)

    return turtle.Vec2D(*stash)

def print_click_position():
    x, y = get_click_position()
    print('{0}, {1}'.format(x, y))

    turtle.ontimer(print_click_position, 1000)

turtle.onscreenclick(get_click_position)
print_click_position()

turtle.mainloop()

Call get_click_position() with no arguments if you want to know what the last click occured. It will keep returning that result until a new click comes in, at which time get_click_position() is invoked as an event handler with arguments.

Upvotes: 0

Blckknght
Blckknght

Reputation: 104792

The callback function you pass to onscreenclick can do whatever it wants with the x and y values it gets called with. It's not really clear what you want to do, but it's pretty hard to imagine that you can't find a way to do it in a function.

If you're concerned about how you can pass the values around without using global variables, perhaps the best way would be to have the callback be a method in a class, so that it can assign attributes that other methods can easily read:

import turtle

class Foo:
    def __init__(self):
        self.click_x = 0  # initialize with dummy values
        self.click_y = 0
        turtle.ontimer(self.other_method, 1000)

    def click_cb(self, x, y):
        self.click_x = x
        self.click_y = y

    def other_method(self):
        print(self.click_x, self.click_y)
        turtle.ontimer(self.other_method, 1000)

foo = Foo()
turtle.onscreenclick(foo.click_cb)

turtle.mainloop()

Upvotes: 2

Related Questions