I am having this issue as well. If anyone has any more recommendations to fix it, that would be super helpful! I have tried both ratingScale and Slider using Psychopy3 and it remains an issue…
UPDATE: issue only occurs when in fullscreen mode
from psychopy import visual
from psychopy import gui, data, core,event
import csv
import time
from time import localtime, strftime, gmtime
from datetime import datetime
import os.path
import pyglet
def close():
"""Quits experiment if user presses 'escape' key."""
if 'escape' in event.getKeys():
print ("User exited")
win.close()
outputfile.close()
core.quit()
# User should set cwd to the experiment directory
os.chdir('\\\\storage.its.york.ac.uk\\pshome\\blam500\\Downloads\\movie_study_0.8')
# User should set directory for output files to be stored
save_path= '\\\\storage.its.york.ac.uk\\pshome\\blam500\\Downloads\\movie_study_0.8\\output\\questionnaire'
# Create a dictionary to store information from the dialogue box
inputbox = {'expdate': datetime.now().strftime('%Y%m%d_%H%M'),'part_number':'','videoCondition':''}
# Create dialogue box
# user enters participant number + video condition (i.e. the Header of the column of video lists in the film csvFile)
dlg=gui.DlgFromDict(inputbox, title = 'Input participation info',
fixed='expdate',
order=['expdate', 'part_number','videoCondition'])
# If the user doesn't press ok, the programme will quit and inform user.
if not dlg.OK:
print ("User exited")
core.quit()
# Function to present thought probes, store responses and present break screen in between videos
# If it is the last trial, presents end screen instead of break screen
def thought_probes (video_name, participant_number, last=0):
# Use trialhandler to present thought probes from csv file in random order
Questionnaire = data.TrialHandler(nReps = 1, method = 'random', trialList = data.importConditions('references\\questions.csv'), name = 'Questionnaire')
# Create rating scale for user to rate thought probes
ratingScale = visual.RatingScale(win, low=1, high=10, markerStart=4.5,
precision=10,
leftKeys='1', rightKeys='2', acceptKeys='4', scale = None, labels = None1)
# Create text stimulus for thought probe presentation
QuestionText = visual.TextStim(win, color = [-1,-1,-1], alignHoriz = 'center', alignVert= 'top', pos =(0.0, 0.3))
# Create text stimuli for low and high scale responses
Scale_low = visual.TextStim(win, pos= (-0.5,-0.5), color ='black')
Scale_high = visual.TextStim(win, pos =(0.6, -0.5), color ='black')
# Make thisRunDict global so that it can be accessed outside of function to write to outputfile
global thisRunDict
# Store participant number and video name in thisRunDict to write to outputfile
thisRunDict= {'Participant_number': str(participant_number),'videoName': video_name }
# Loop through each thought probe in the Questionnaire created above using trialhandler
for question in Questionnaire:
ratingScale.noResponse = True
# added section for keyboard handling
key = pyglet.window.key
keyState = key.KeyStateHandler()
win.winHandle.push_handlers(keyState)
pos = ratingScale.markerStart
inc = 0.1
# While there is no response from user, present probe and scal
while ratingScale.noResponse:
close()
if keyState[key._1] is True:
pos -= inc
elif keyState[key._2] is True:
pos += inc
if pos > 9:
pos = 9
elif pos < 0:
pos = 0
ratingScale.setMarkerPos(pos)
# Set text of probe and responses
QuestionText.setText(question['Questions'])
Scale_low.setText(question['Scale_low'])
Scale_high.setText(question['Scale_high'])
# draw text stimuli and rating scale
QuestionText.draw()
ratingScale.draw()
Scale_low.draw()
Scale_high.draw()
# Store response using getRating function
responded = ratingScale.getRating()
win.flip()
# reset marker to middle of scale
ratingScale.setMarkerPos((0.5))
# For each probe, store probe label and response in thisRunDict
thisRunDict[ str(question['Label'] )] = str(responded)
# Create text stimuli to be updated for breaks and end screen
stim = visual.TextStim(win, "", color = [-1,-1,-1], wrapWidth = 800)
# Present break screen at the end of each set of questions
if last==0:
stim.setText("""You are welcome to take a break if you need to.
\nPress enter when you are ready to continue.""")
stim.draw()
win.flip()
# Wait for user to press Return to continue
key = event.waitKeys(keyList=(['return']), timeStamped = True)
close ()
else:
# Presents end screen at the end of task
stim.setText("""You have reached the end of the experiment.
\nPlease let the experimenter know you have finished.
\nThank you for your participation.""")
stim.draw()
win.flip()
# Waits for user to press escape to exit experiment
key = event.waitKeys(keyList=(['return']), timeStamped = True)
close ()
# Store participant number, video condition and experiment date provided by user as variables for later use
part_number = inputbox['part_number']
videoCondition = inputbox['videoCondition']
expdate = inputbox['expdate']
# create filename based on user input
filename = '{}_{}_{}.csv'.format(inputbox['part_number'], inputbox['expdate'],inputbox['videoCondition'])
# update filename to include absolute path so that it is stored in output directory
completeName = os.path.join(save_path, filename)
# open file for writing
outputfile = open(completeName, "w", newline = '')
# Create list of headers for output csv file
fieldnames = ['Participant_number', 'videoName','Video_startTime','Video_endTime','Questionnaire_startTime','Questionnaire_endTime',
'TrialDuration','Focus','Future','Past','Self','Other','Emotion','Modality','Detailed','Deliberate','Problem','Diversity','Intrusive','Source']
# create variable which calls DictWriter to write to outputfile and specifies fieldnames
writer = csv.DictWriter(outputfile, fieldnames)
# writes headers using fieldnames as specified above when creating writer variable
writer.writeheader()
# Use trialhandler to sequentially present films listed in filmlist csv file
filmDict = data.TrialHandler(nReps = 1, method = 'sequential', trialList = data.importConditions('references\\filmList.csv'), name = 'filmList')
# Create white window for stimuli to be presented on throughout task
#win = visual.Window(size =[1024, 768], fullscr = True, allowGUI = False, units = "pix", color = (1,1,1), monitor="testMonitor")
win = visual.Window(size=[1024, 768], color=[1,1,1,], monitor="testMonitor", fullscr= True, allowGUI = False)
# Create text stimuli to be updated for start screen instructions
stim = visual.TextStim(win, "", color = [-1,-1,-1], wrapWidth = 1300, units = "pix", height=40)
# Update text to include instructions for task
stim.setText("""You will be presented with several videos.
\nThese videos will contain dangerous behaviour, strong language, disturbing images,threat and violence.If you find these types of videos distressing ,please do not participate and let the experimenter know.
\nIf at any point, you become distressed and would like to stop the task, please inform the experimenter.
You will not be penalised for withdrawing from the study.
\nAt the end of each video, you will be asked to rate several statements regarding the nature of your ongoing thoughts on a sliding scale.
Use the mouse to move the marker and press enter when you are happy with your selection.
\nPress Enter to begin.""")
# draw text stimuli
stim.draw()
# flip window to show text
win.flip()
close()
# Wait for user to press Return to continue
key = event.waitKeys(keyList=(['return']), timeStamped = True)
close()
# Start a clock right before the experiment starts
tasktime = core.Clock()
tasktime.reset()
# Loop through each film stored in filmDict created above using trialhandler
for film in filmDict:
# store trial start time for later use in calculating trial duration
start =time.time()
# store when the video started to later store in outputfile, this videoStart uses clock created at start of experiment
videoStart = tasktime.getTime()
# present movie using moviestim2
mov = visual.MovieStim3 (win, film[videoCondition], size=(1920, 1080), flipVert=False, flipHoriz=False, loop=False)
while mov.status != visual.FINISHED:
mov.draw()
win.flip()
close()
# store when the video ends to later store in outputfile, this videoEnd uses clock created at start of experiment
videoEnd = tasktime.getTime()
# If statement to either present break screen or end screen
nextTrial = filmDict.getFutureTrial(n=1) #fixes error for end screen
if nextTrial is None or nextTrial[videoCondition] != None:
# when the video has ended, call thought_probes function to present probes and rating scale
thought_probes(film[videoCondition], part_number)
else:
thought_probes(film[videoCondition], part_number,1)
# store when the questions end to later store in outputfile, this qEnd uses clock created at start of experiment
qEnd = tasktime.getTime()
# store trial end time for later use in calculating trial duration
end =time.time()
# calculate trial duration to store in outputfile
trial_duration = (end-start)
# add timings to global thisRunDict to write to outputfile below
thisRunDict['Video_startTime']= str(videoStart)
thisRunDict['Video_endTime']= str(videoEnd)
thisRunDict['Questionnaire_startTime']= str(videoEnd)
thisRunDict['Questionnaire_endTime']= str(qEnd)
thisRunDict['TrialDuration'] = str(trial_duration)
# write responses and timings stored in thisRunDict to outputfile
writer.writerows([thisRunDict])
outputfile.flush()