Reputation: 229
Using the code below, I'm trying to open a window for 10 seconds, have the user click anywhere on the screen as many times as they wish, and I want to log the mouse click locations. Every time the user clicks within the window (i.e. myMouse.getPressed) occurs, I'm appending the click location to a list (mouse_click_locations[]). However, the list is being appended with the same click location many times, on every frame. I want to append the click location to the list once, and no more until another click is initiated. I thought that adding 'myMouse.clickReset()' at the end of each frame would do this, but it doesn't make a difference.
After 10 seconds, I want the list to be populated with one location (x,y coord) for each mouse click initiated.
from psychopy import visual, core, gui, event, sound
win = visual.Window([800,600],color=(1,1,1), colorSpace='rgb',
rgb=None, allowGUI=True, monitor='testMonitor',
units='deg', fullscr=False)
myMouse = event.Mouse(visible=True,win=win)
refresh_rate = 60.0
default_time = 10
time_window = default_time * refresh_rate
time_window = int(time_window)
running = 1
while running:
mouse_click_locations = []
for frame in range(time_window):
mouse_loc = myMouse.getPos()
mouse_click = myMouse.getPressed()
if mouse_click:
mouse_click_locations.append(mouse_loc)
win.flip()
myMouse.clickReset()
running = 0
win.close()
print mouse_click_locations
Could someone help me achieve this? am I using myMouse.clickReset() incorrectly?
Cheers, Jon
Upvotes: 1
Views: 709
Reputation: 5683
This happens because the script checks the mouse state for every iteration in your frame-loop; i.e. 60 times a second. As you say, you only want to get a single event for each mouse-down. Here's one solution where you simply halt the script until all buttons are released. Also note the use of any
to explicitly check all buttons.
# Record mouse position if a key is pressed
if any(myMouse.getPressed()) # Any button pressed, no matter which
mouse_click_locations.append(myMouse.getPos())
# Wait until all buttons are released
while any(myMouse.getPressed()):
pass
No need to use mouse.clickReset
. As a small comment, you do not update visual stuff on the screen, so you do not need to include win.flip
in the loop. Because it waits for the next monitor update, it effectively rounds off reaction times (if you need these) to nearest 1/60 second interval. This, and relying a bit on defaults, would also simplify the script a great deal:
default_time = 10
from psychopy import visual, core, event
win = visual.Window(color='white', monitor='testMonitor', units='deg')
myMouse = event.Mouse(visible=True, win=win)
clock = core.ClocK()
# Collect unique click events before time runs out
mouse_click_locations = []
while clock.getTime() < default_time:
# Record mouse position if a key is pressed
if any(myMouse.getPressed()) # Any button pressed, no matter which
mouse_click_locations.append(myMouse.getPos())
# Wait until all buttons are released
while any(myMouse.getPressed()):
pass
print mouse_click_locations
Upvotes: 2