psychopy.org | Reference | Downloads | Github

Prevent multiple mouse clicks on clickable stimuli

OS: Mac OS X Big Sur 11.3
PsychoPy version: 2021.1.2
Standard Standalone? Yes
What are you trying to achieve?: I am recreating a social rejection task that was previously made in E-Prime 2 in my lab. In the first portion of the task, participants are shown pictures of other gender and age matched “participants.” They are told to select five other participants they would be interested in chatting with. This is done by clicking on one of the photos at the top of the screen. When they click on the photo, the photo replicates at the bottom (in sequential order) and the counter goes up to indicate that their pick has been registered in the computer. The screenshot below shows what it would look like if a male participant chose three other participants:

As a disclaimer, I am incredibly new to Python. This is my first project and I only started learning a few weeks ago. So, it has been a bit of struggle and my code component might not be the most effective and clean way of writing code. I am totally open to suggestions and feedback. With that said, I am having problems with preventing double clicks on the photos.

`This is the code I have in the Begin Routine tab:`
> male_count = 'Males: 0'
> female_count = 'Females: 0'
> photos = [F01, F02, F03, F04, F05, F06, F07, F08, F09, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20]
> male_pos = [(-.72, -.10), (-.60, -.10), (-.48, -.10),(-.36, -.10),(-.24, -.10), (-2, -2)]
> female_pos = [(.72, -.10), (.60, -.10), (.48, -.10),(.36, -.10),(.24, -.10),(-2, -2)]

Here is the Every Frame tab:

> for x in range(0,6):
>     if len(selAmouse.clicked_name) == x and expInfo['gender'] == 'Male':
>         male_count = 'Males:' + str(x)
>         female_count = 'Females: 0'
>         for i in photos: 
>             if selAmouse.isPressedIn(i):
>                 ch = 'F'
>                 name = i.name.lstrip(ch)
>                 pic1 = visual.ImageStim(
>                     win = win,
>                     name = 'pic1',
>                     image=expInfo['gender']+"_"+expInfo['age']+"_" +str(name) +".bmp", mask=None,
>                     ori=0.0, pos= male_pos[x], size=(0.103125, 0.1375),
>                     color=[1,1,1], colorSpace='rgb', opacity=None,
>                     flipHoriz=False, flipVert=False,
>                     texRes=128.0, interpolate=True, depth=-1.0)
>                 pic1.setAutoDraw(True)
>                 photos.remove(i)
>     if len(selAmouse.clicked_name) == x and expInfo['gender'] == 'Female':
>        male_count = 'Males: 0'
>        female_count = 'Females:' + str(x)
>        for i in photos: 
>             if selAmouse.isPressedIn(i):
>                 ch = 'F'
>                 name = i.name.lstrip(ch)
>                 pic1 = visual.ImageStim(
>                     win = win,
>                     name = 'pic1',
>                     image=expInfo['gender']+"_"+expInfo['age']+"_" +str(name) +".bmp", mask=None,
>                     ori=0.0, pos= male_pos[x], size=(0.103125, 0.1375),
>                     color=[1,1,1], colorSpace='rgb', opacity=None,
>                     flipHoriz=False, flipVert=False,
>                     texRes=128.0, interpolate=True, depth=-1.0)
>                 pic1.setAutoDraw(True)
>                 photos.remove(i)

What did you try to make it work?: I’ve tried simply removing the object from the list of photos that the loop pulls from, but this doesn’t prevent the object from being clickable. It just prevents the object from showing up. So, a participant could still theoretically click the same photo and have psychopy register it as a valid click.

What specifically went wrong when you tried that?: When I tried this, I was still able to double click the photo. It registered as a click, causing the counter to go up and a blank space to appear where the next sequential photo should be.

Thanks so much in advance!

Hi There!

Your approach is in the right direction that’s for sure! This demo does something similar but with letters:
replicateDemo.psyexp (13.9 KB)

In the begin routine tab we define a list of things that can be clickable, along with an empty list of things already clicked:

clickableStimuli = [letterA, letterB, letterC]
selectedLetters = []
#A starting position along the x axis
thisX = -.5

Then in the eachframe tab we monitor if each thing has been clicked and if we have we remove it from the clickable list and draw a new stimulus:

for stim in clickableStimuli:
    if mouse.isPressedIn(stim):
        newLetter = visual.TextStim(win=win, name='letterA',
        text='A',
        font='Open Sans',
        pos=(-.5, 0), height=0.1, wrapWidth=None, ori=0.0, 
        color='white', colorSpace='rgb', opacity=None, 
        languageStyle='LTR',
        depth=0.0);
        newLetter.text = stim.text
        newLetter.pos = [thisX, -.4]
        thisX += 0.1 # increment the next X position
        selectedLetters.append(newLetter)#add this stim to a list of stimuli to be drawn at bottom of screen
        clickableStimuli.remove(stim)# remove this stim from the list of clickables

#draw all selected letters
for selectedLet in selectedLetters:
    selectedLet.draw()

Each time something is selected, we increment the x coordinate so that each new selected stim is drawn in a new location!

Hope this helps,
Becca