| Reference | Downloads | Github

Move the slider maker with keys/mouse and record continuous ratings

If this template helps then use it. If not then just delete and start from scratch.

OS (e.g. Win10): Win10
PsychoPy version (e.g. 1.84.x): Psychopy 3
Standard Standalone? (y/n) If not then what?: y
What are you trying to achieve?:
Dear users,

I’m new to psychopy and python so sorry if I missed anything and/or the question is too simple.
I will show participants sequences of video clips. While watching, participants rate the valence of each video continously on a 0-100 scale.

Three things I’m confused:

  1. I have a slider and I’m trying to add a code component so that participants can either use the “left” and “right” keys, OR the mouse to move the marker continuously (without tapping or clicking), which means they should either press and hold keys, OR simply move the mouse without clicking to move the slider. How could I accomplish this? Either the keyboard plan or the mouse plan would work.
  2. And if it is possible, how could I record the continuous ratings for each video clip (and timestamp the ratings)?
  3. How could I set the starting position of the marker in the current trial to the end position of the previous trial?

What did you try to make it work?:
For the “keyboard” plan:
I’ve tried the code in this post: Controlling slider with keyboard which showed how to use left and right keys to move slider.

# Begin routine
slider.markerPos = 50

# Each frame
keys = event.getKeys()
if len(keys):
    if 'left' in keys:
        slider.markerPos = slider.markerPos - 1
    elif 'right' in keys:
        slider.markerPos = slider.markerPos + 1

There are two problems with this one:

  1. Need to tap the keys again and again to move the marker, but what I want is “press and hold”.
  2. The slider starts at a specific place, but I want it to start at the end position of a previous trial. I tried sth like “slider.markerPos = slider.markerPos” in the Begin routine tab but the marker won’t show up this time.

I’ve tried to modify the code provided this this stack overflow post PsychoPy - Move RatingScale marker continuously on key-down as below. But the experiment won’t run without throwing an error.

# Begin experiment
from psychopy.iohub import launchHubServer, EventConstants
io = launchHubServer(experiment_code='key_evts', psychopy_monitor_name='default')
keyboard = io.devices.keyboard

# Begin routine
increment = 0 # initial value of increment

# Each frame
for event_io in keyboard.getEvents():
    if event_io.type == EventConstants.KEYBOARD_PRESS:
        if event_io.key == u'right':
            increment = 1 # move one step to the right
        elif event_io.key == u'left':
            increment = -1 # move one step to the left
    if event_io.type == EventConstants.KEYBOARD_RELEASE:
        increment = 0 # stop changing position

if 0 < slider.markerPos < 100:
    slider.markerPos += increment

I’ve also tried the “press and hold keys” JS in this post Press and Hold Key to Move Slider by modifying some parameters, but the experiment won’t even run and I’m not getting any error.

For the mouse plan:
I’ve tried the code in this post Is it possible to make a slider object only interactable by dragging the marker?. The code works but I need to click on the mouse to drag. What I want is simply moving the mouse to move the slider.

I’ve searched online for many days and still have no clue about how I could realize this, and record the continuous ratings from the keys/mouse (and timestamp the ratings), and set the starting position of the marker in the current trial to the end position of the previous trial? Any help would be appreciated!

I’m not sure if it’s possible to interact with a slider using mouse hover but I could easily build you a bespoke slider which does this using a similar principle to my Affect Grid demo.

Actually there maybe a way to update a slider component using the mouse hover.

Also, holding down the arrow key for continuous movement should work online but would need more work to implement offline.

Hi Wakefield! Thanks for your quick reply. I’m not very familiar with coding in either python/javascript but I’m learning. This experiment will eventually be online so a method that works online would also be great.
If using mouse, feels like I could update the marker position according the mouse position, and restrict mouse position to the line of the slider.
I’d appreciate if you have some ideas on coding this.

Here’s today’s attempt at an interactive slider demo.

I still need to work out a few things like label wrap width and marker colour online but the marker position can be moved used arrow keys or mouse hover and is submitted using enter/return or a mouse click.

Thank you so much! I will try it.

Hi Wakefield! I’ve tried to modify your program so that it fits with my valence ratings on emotional film clips. Now I decide to use mouse only so I either deleted/or commented out codes for the keyboard. Hope I haven’t messed things up with my limited knowledge. Do you mind checking what I have? It won’t run offline without errors and reports several errors online (let me know if you cannot get access). Experiment | mengsili/interactivecontinousratnig (
When I ran it online first, it says “mouse is not defined”, so I added a mouse component.

Then when I ran it again it said this:

Despite this, what I’m still confused is how could I set the start position of the marker to the end position of a previous trial?

I really appreciate your time and help. That’s so nice of you.

I don’t have much time at the moment to look. However, try removing oldRating = -1 from Begin Routine and you need Array.prototype.append = [].push; in code_JS. Take a look at the code in my start routine. I’m guessing you didn’t use it since you got the mouse error.

Sorry I missed code_JS before. I saw it just now in your crib sheet. Now it showed the first trial and then stuck there–could be that I have deleted some lines of codes incorrectly. I will keep on working this. Thanks again!
Experiment | mengsili/interactive-slider-continous-rating (

You seem to have deleted (rather than commented out)

if mouse.isPressedIn(slider_shape):

I set the duration of the slider to the duration of the film clip. Would that work? I actually want to end with the film instead of clicking the mouse.

Try disabling the video component.

Then try disabling the slider and just having the video. Did the video work before?

Also check my crib sheet for video tips and this forum for information about videos sticking.

Hi Wake–I thought I’d get back to you that I finally make things work both online and offline, though it took a few days! I tried a lot tips you and others shared about the movie but nothing worked. It turned out that I just needed to set the movie duration to be three decimals in the condition file…I will post my final codes below in case other people can benefit from it. Thank you so much for all your help.

For the current demo:

  • Subjects rate their emotions on a 0-100 scale (from “very negative” to “very positive”) while viewing movie clips.
  • The slider marker can be moved by simply moving the mouse within the area of the slider (without clicking).
  • Each trial ends when the video ends.
  • Continuous ratings (every 3 frame) can be saved along with the rating time.
  • The slider marker starts at the end position of a previous trial.

Note: To make the exp work properly, you need to add a mouse component named “mouse” in the first routine.

For code_JS (set code type to be JS for running online):

# Begin Experiment
shuffle = util.shuffle;
Array.prototype.append = [].push;

For codeOnlineRating:

# Begin Experiment

# Change the following parameters according to your own exp
slider_width = 1
slider_height = .05
slider_orientation = 0
#Failing to set ticks or labels in code
slider_ticks=[0, 100]
slider_labels=['Very positive','Very negative']
slider_granularity = .1
slider_decimals = 1
slideSpeed = 3
oldRating = 50

# Begin Routine

if slider_granularity == 0:
    slider_granularity = .1

# frame counter
thisFrame = 0

# create an empty list to store data

# set start position of the slider to end position of the previous trial
slider.markerPos = oldRating

# record the current position of the mouse

# Each Frame

# Create a slider_shape in this routine with the same size as the slider
# Check if mouse is moving within slider_shape, if so change marker position accordingly
if slider_shape.contains(mouse) and mouse.getPos()[slider_orientation] != mouseRec[slider_orientation]:
    mouseRec = mouse.getPos()
    slider.markerPos = mouseRec[slider_orientation]/slider_width*(slider_ticks[-1]-slider_ticks[0])+(slider_ticks[0]+slider_ticks[-1])/2
# update oldRatings if 
if slider.markerPos:
     if oldRating != slider.markerPos:
        oldRating = slider.markerPos

# for now slideSpeed = 3, so ratings and time saved for every 3 frame
thisFrame += 1
if slider.markerPos and thisFrame%slideSpeed==0:

# End Routine 

# save continous ratins to the data file
thisExp.addData('All Responses',slider_data)
#thisExp.addData('Final Response',round(slider.markerPos,slider.decimals))
print('All Responses',slider_data)
#print('Final Response',round(slider.markerPos,slider.decimals))