# Adaption of Touch Screen Double Tapping

**URL:** <https://discourse.psychopy.org/t/adaption-of-touch-screen-double-tapping/33179>\
**Category:** Coding\
**Created:** [February 7, 2023, 10:40pm UTC](https://discourse.psychopy.org/t/adaption-of-touch-screen-double-tapping/33179 "2023-02-07T22:40:21Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![vroni.hischa](https://avatars.discourse-cdn.com/v4/letter/v/48db29/32.png) [@vroni.hischa](https://discourse.psychopy.org/u/vroni.hischa)\
**Post date:** [February 7, 2023, 10:40pm UTC](https://discourse.psychopy.org/t/adaption-of-touch-screen-double-tapping/33179/1 "2023-02-07T22:40:21Z")

</div>

Hi everyone,  
first things first 🙂  
OS: Win10  
PsychoPy version: v2022.2.5

I used PsychoPy to do a number line estimation task for children using a touch laptop.  
In the task there is a line (slider) shown from 0 to 10 or 100 and the kid has to guess the position of a certain number within this line.  
The problem is that at the moment the kid would have to double tap in order to give the answer. I would prefer that a single tap would be enough.  
I already read some posts (see below) that describe the same problem but unfortunately their solutions did not work out for me (PsychoPy stopped with exit code 1 or the slider was not clickable anymore).

It would be really great if anyone could help me.  
As i don’t have a lot of experience with coding, i tried to copy the important part from my code (you will find that below). Could you tell me which commands i have to use and where to put them into the code?  
Let me know, if any important information is missing that would be needed to get help here 🙂

Thanks in advance 🙂

# — Prepare to start Routine “startbildschirm” —

continueRoutine = True  
routineForceEnded = False

# update component parameters for each repeat

# setup some python lists for storing info about the mouseja

mouseja.x =   
mouseja.y =   
mouseja.leftButton =   
mouseja.midButton =   
mouseja.rightButton =   
mouseja.time =   
mouseja.clicked\_name =   
gotValidClick = False # until a click is received

# keep track of which components have finished

startbildschirmComponents = [textstartmessage, imageja, mouseja, imagenemo]  
for thisComponent in startbildschirmComponents:  
thisComponent.tStart = None  
thisComponent.tStop = None  
thisComponent.tStartRefresh = None  
thisComponent.tStopRefresh = None  
if hasattr(thisComponent, ‘status’):  
thisComponent.status = NOT\_STARTED

# reset timers

t = 0  
\_timeToFirstFrame = win.getFutureFlipTime(clock=“now”)  
frameN = -1

# — Run Routine “startbildschirm” —

while continueRoutine:  
# get current time  
t = routineTimer.getTime()  
tThisFlip = win.getFutureFlipTime(clock=routineTimer)  
tThisFlipGlobal = win.getFutureFlipTime(clock=None)  
frameN = frameN + 1 # number of completed frames (so 0 is the first frame)  
# update/draw components on each frame

```
# *textstartmessage* updates
if textstartmessage.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
    # keep track of start time/frame for later
    textstartmessage.frameNStart = frameN # exact frame index
    textstartmessage.tStart = t # local t and not account for scr refresh
    textstartmessage.tStartRefresh = tThisFlipGlobal # on global time
    win.timeOnFlip(textstartmessage, 'tStartRefresh') # time at next scr refresh
    # add timestamp to datafile
    thisExp.timestampOnFlip(win, 'textstartmessage.started')
    textstartmessage.setAutoDraw(True)

# *imageja* updates
if imageja.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
    # keep track of start time/frame for later
    imageja.frameNStart = frameN # exact frame index
    imageja.tStart = t # local t and not account for scr refresh
    imageja.tStartRefresh = tThisFlipGlobal # on global time
    win.timeOnFlip(imageja, 'tStartRefresh') # time at next scr refresh
    # add timestamp to datafile
    thisExp.timestampOnFlip(win, 'imageja.started')
    imageja.setAutoDraw(True)
# *mouseja* updates
if mouseja.status == NOT_STARTED and t >= 0.0-frameTolerance:
    # keep track of start time/frame for later
    mouseja.frameNStart = frameN # exact frame index
    mouseja.tStart = t # local t and not account for scr refresh
    mouseja.tStartRefresh = tThisFlipGlobal # on global time
    win.timeOnFlip(mouseja, 'tStartRefresh') # time at next scr refresh
    # add timestamp to datafile
    thisExp.addData('mouseja.started', t)
    mouseja.status = STARTED
    mouseja.mouseClock.reset()
    prevButtonState = mouseja.getPressed() # if button is down already this ISN'T a new click
if mouseja.status == STARTED: # only update if started and not finished!
    buttons = mouseja.getPressed()
    if buttons != prevButtonState: # button state changed?
        prevButtonState = buttons
        if sum(buttons) > 0: # state changed to a new click
            # check if the mouse was inside our 'clickable' objects
            gotValidClick = False
            try:
                iter(imageja)
                clickableList = imageja
            except:
                clickableList = [imageja]
            for obj in clickableList:
                if obj.contains(mouseja):
                    gotValidClick = True
                    mouseja.clicked_name.append(obj.name)
            if gotValidClick:
                x, y = mouseja.getPos()
                mouseja.x.append(x)
                mouseja.y.append(y)
                buttons = mouseja.getPressed()
                mouseja.leftButton.append(buttons[0])
                mouseja.midButton.append(buttons[1])
                mouseja.rightButton.append(buttons[2])
                mouseja.time.append(mouseja.mouseClock.getTime())
            if gotValidClick:
                continueRoutine = False # abort routine on response

# *imagenemo* updates
if imagenemo.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
    # keep track of start time/frame for later
    imagenemo.frameNStart = frameN # exact frame index
    imagenemo.tStart = t # local t and not account for scr refresh
    imagenemo.tStartRefresh = tThisFlipGlobal # on global time
    win.timeOnFlip(imagenemo, 'tStartRefresh') # time at next scr refresh
    # add timestamp to datafile
    thisExp.timestampOnFlip(win, 'imagenemo.started')
    imagenemo.setAutoDraw(True)

# check for quit (typically the Esc key)
if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]):
    core.quit()

# check if all components have finished
if not continueRoutine: # a component has requested a forced-end of Routine
    routineForceEnded = True
    break
continueRoutine = False # will revert to True if at least one component still running
for thisComponent in startbildschirmComponents:
    if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
        continueRoutine = True
        break # at least one component has not yet finished

# refresh the screen
if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
    win.flip()

```

# — Ending Routine “startbildschirm” —

for thisComponent in startbildschirmComponents:  
if hasattr(thisComponent, “setAutoDraw”):  
thisComponent.setAutoDraw(False)

# store data for thisExp (ExperimentHandler)

thisExp.addData(‘mouseja.x’, mouseja.x)  
thisExp.addData(‘mouseja.y’, mouseja.y)  
thisExp.addData(‘mouseja.leftButton’, mouseja.leftButton)  
thisExp.addData(‘mouseja.midButton’, mouseja.midButton)  
thisExp.addData(‘mouseja.rightButton’, mouseja.rightButton)  
thisExp.addData(‘mouseja.time’, mouseja.time)  
thisExp.addData(‘mouseja.clicked\_name’, mouseja.clicked\_name)  
thisExp.nextEntry()

# the Routine “startbildschirm” was not non-slip safe, so reset the non-slip timer

routineTimer.reset()

**One of the posts that i tried to use was the following (unfortunately it did not work):**

> [@Touch Screen press modification](https://discourse.psychopy.org/t/touch-screen-press-modification/23046/1):
>
> Hi everyone,  
> I am here posting to discuss how I modified my experiment to respond to a single tap from a touch screen. Originally I had an issue where the experiment I was working on required a user to double tap a screen or to tap and hold the screen for the experiment to register the response. This was not ideal and the result was a forced effort to get the system to register a response.
> 
> What I learned was that I could solve this using the code module in the builder. With the advice from Rebecca Hirst I was able to implement a hover method that resulted in the desired functionality. At the beginning of the routine a set of if statements are checked to see if the “mouse” (user’s cursor of where they will tap) is within one of the given images/shapes. If so the response is measured and the experiment continues.
> 
> Within the code module I added the following functionality.
> 
> At **Begin Routine**  
> I reset the cursor’s position with the setPos() function.
> 
> At **Each Frame**  
> I setup the if statements responsible for handling a press or “hover”.
> 
> if CorrectTarget.contains(Mouse/Curosr):  
> Set Correct response text  
> Set Correct response message  
> Set Correct response audio  
> ContinueRoutine = False
> 
> if IncorrectTarget.contains(Mouse/Curosr):  
> Set Incorrect response text  
> Set Incorrect response message  
> Set Incorrect response audio  
> ContinueRoutine = False
> 
> With the following implementation I was able to achieve the functionality for my experiment. Users can make an effortless single tap and the experiment will record the response appropriately.
