Use touch coordinates to draw element
I'm trying to create a task involving a touchscreen response wherein participants listen to a recording while looking at a picture on screen. This sketchpad is then replaced by a second screen where participants see a line of text and a circle, and perform their response. Then, participants will touch somewhere around the circumference of the circle, and I then need an arrow element to be drawn with the tip coordinates corresponding to the coordinates of the touch response.
To do all this I'm using the inline script below, which displays the circle and instructions correctly, but does not seem to register a response or draw the arrow element. From what I gather from the documentation, a touch response is effectively equivalent to a mouse click, so I'm using the get_click() function to record the "key" press, position, and time (I will need response time as well). I suspect I might be going wrong when trying to unpack and reference the "position" tuple, but maybe the problem is elsewhere?
DISCLAIMER: I'm very much a Python noob.
my_canvas = canvas()
my_mouse = mouse()
while True:
my_canvas.clear()
my_canvas.text("INSERT INSTRUCTIONS HERE", center=True, x=0.0, y=372.0, color='white')
my_canvas.circle(0, 0, 300, color='white')
t0 = my_canvas.show()
my_canvas.show()
button, position, t1 = my_mouse.get_click()
var.x = position[0]
var.y = position[1]
my_canvas.arrow(0, 0, var.x, var.y, body_length=0.8, body_width=0.5, head_width=30)
Comments
Hi Fabio,
You are almost there, the response are collected and the arrow is constructed. However, you need to 'flip' the canvas to update the screen once a response has been collected. Simply add
my_canvas.show()
at the end of your script and it should work.You can test this by adding print statements throughout the script (e.g.
print('The cursor was at (%d, %d)' % (x, y))
)Best,
Laurent
I noticed that I was asking it to draw the tip at the click position, while also accidentally trying to force a fixed arrow length, so I changed the code as follows:
However, this doesn't seem to work either, and produces the following error:
TypeError: arrow() takes at least 5 arguments (6 given)
I know that the variables xpos, ypos, and arrow_length are being calculated correctly, because they are saved in the variable inspector.
Ok, progress! I've added the my_canvas.show() line as you suggested, and It seems to be doing something, at least with the PsychoPy backend. Is there a way to make the cursor visible, at least for testing on Windows? That way I know where the arrow should be drawn. At the moment, it looks rather odd, no matter where I click (not that I can tell where I'm clicking). Also, the arrow doesn't persist on the screen, but disappears when I unclick. Is there a way to change that?
EDIT: Silly me. Removing the body_length argument altogether fixed the weirdness.
Hi Fabio,
Good to see progress!
If the experiment is designed for a touch-based device (e.g. an Android tablet), it is required to use the Droid back-end.
Adding
my_mouse.show_cursor(show=True)
should work, but depending on the back-end and version of OS it is not always as consistent. See:Sure! Add something like
clock.sleep(1000)
at the end of the script, where the number is the amount of time you want to display the cursor in ms.Thanks Laurant, that helps a lot! What if I wanted to give participants the chance to change their response (i.e. re-orient the arrow) and then confirm it by pressing on a button (that would appear in the middle of the circle after the arrow was first position and would stay there until the answer is confirmed)?
Basically, the canvas should remain until the participant clicks on the button. I know how to load the image file, but I'm not sure how to turn it into an interactive button.