Here is my guess what happens:
Due to using “wait”, Windows cannot dispatch the touch event to your PsychoPy window. Thus, windows assumes that the window is unresponsive and offers the possibility to close your PsychoPy experiment.
If I am correct, replacing the “wait” code with a while loop flipping the window until the audio file is finished should solve the problem.
Try this:
REPLACE
if time <= 0:
wait(audio.getDuration()+0.5)
else:
wait(time)
WITH
if time <= 0:
time = audio.getDuration()+0.5
timer = core.CountdownTimer(time)
while timer.getTime() > 0:
win.flip()
–> note that you need to pass the reference to your window to your function, in my case called “win”
Just a side note:
Is your experiment detecting all touches as mouse click events? In my case, only touches including a small swipe were detected as click events, but not a touch on the screen without finger motion.
Just in case your are facing the same issue, here is the solution I developed to deal with this issue:
# How to use:
#
# Replace old code, such as
# my_mouse = event.Mouse()
#
# with the complete following code:
# Ensures that also touch events without swipe motion are registered as mouse clicks in PsychoPy (tested with Surface Pro Tablets)
# Note:
# - short touch: left mouse button press, long touch: right mouse button press
# - ensure to check for mouse clicks after each win.flip(). Best practice: call win.flip() only once at the end of each trial processing loop -> Otherwise you might miss touch events without swipe motion
# Author: Frank Papenmeier, frank.papenmeier@uni-tuebingen.de, Oct 12 2017
import types
class TouchMouse(event.Mouse):
def __init__(self, visible=True, newPos=None, win=None):
event.Mouse.__init__(self, visible, newPos, win)
self._last_frames = 0
self._updatePressed() # call once to initialize self._buttons
self.win.flip = types.MethodType(self._flip_and_update, self.win.flip) # update pressed state after each flip to ensure that pressed state stays current throughout each flip cycle
def _flip_and_update(self, win_flip):
# Update pressed status only once per window flip
win_flip()
self._updatePressed()
def _updatePressed(self):
buttons, times = event.Mouse.getPressed(self, True)
self._buttons = buttons[:]
if hasattr(self, '_times'): # available beginning with second pass
for i in range(len(self._buttons)):
if times[i] != self._times[i]: # self._times are times of last frame; thus: was there a change in times? If yes, then there was a touch event
self._buttons[i] = 1
self._times = times[:] # make copy in order to save old state (otherwise it is always identical with original times)
def getPressed(self, getTime=False):
if getTime:
return self._buttons, self._times
else:
return self._buttons
def clickReset(self, buttons=(0, 1, 2)):
event.Mouse.clickReset(self, buttons)
self._times = event.mouseTimes[:] # prevent fake click that would otherwise occur after calling clickReset
my_mouse = TouchMouse()