Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Supported by

[solved] Implementing a Slider

edited October 2011 in OpenSesame

Hello,

I am hoping to run a study in OpenSesame where subjects will hear a speech sample and then use a slider to rate naturalness, intelligibility, etc. Does anyone have any insight on how I might to this. I have found python code that runs a slider widget (http://effbot.org/tkinterbook/scale.htm), but it does not work very well when I try to use the 'inline_script' function (the widget will pop up but you can only see it when you exit the experiment). Thank you in advance.

Thanked by 1RKempner

Comments

  • edited October 2011

    Hi Mpaullin,

    Welcome to the forum and thank you for your interest in OpenSesame!

    The problem with using widgets (Tk, Qt, Gtk, and what have you) is that they typically draw on their own window, and not on the OpenSesame window. This is why you see the widget only after the experiment closes (and perhaps in a separate window if you don't run the experiment fullscreen?)

    There are a number things you can do:

    • The questionnaire plug-ins have a rating scale. If this suits your needs, this is probably the best and easiest way to go. http://osdoc.cogsci.nl/plug-ins/questionnaire-plug-ins

    • If you really need a slider, you will basically have to program one in Python inline code. But this is not that hard to do. If you tell me specifically what you want to do, I can give you some pointers.

    Hope this helps!

    Kindest regards,
    Sebastiaan

    There's much bigger issues in the world, I know. But I first have to take care of the world I know.
    cogsci.nl/smathot

  • edited 2:39AM

    Thanks a lot for your helpful reply. I took a look at the rating scale plugin, and I'm afraid that it does not meet my needs. I'm looking for something that can give me a lot more variability, which is why a slider would work best. In the past we used a slider with about 200 underlying data points. I am not a programmer in any sense, so would appreciate any tips you may have for implementing a slider using python inline code. Thanks again

  • edited 2:39AM

    Here's a small snippet that shows a mouse-controlled slider. You will probably want to modify it a bit, but hopefully it conveys the general idea. You can find more about the canvas functions (for drawing) here: http://osdoc.cogsci.nl/python-inline-code/canvas-functions

    You will need to paste this code into the run phase of an inline script item. I've tested it with OpenSesame 0.25-pre9, but it should work with 0.24 as well.

    from openexp.canvas import canvas
    from openexp.mouse import mouse
    my_canvas = canvas(self.experiment)
    my_mouse = mouse(self.experiment, timeout=20)
    
    # Set slider dimensions
    slider_w = 500
    slider_h = 10
    slider_x = self.get("width")/2-slider_w/2
    slider_y = self.get("height")/2-slider_h/2
    
    while True:
    
        # Determine the slider fill based on the mouse position
        pos, time = my_mouse.get_pos()
        x, y = pos
        slider_fill = min(slider_w, max(0, x-slider_x))
    
        my_canvas.clear()
        # Draw some text (this can be anything)
        my_canvas.text("Question goes here", y=slider_y-100) 
        my_canvas.text("Click to accept ...", y=slider_y+100) 
        # Draw the slider frame
        my_canvas.rect(slider_x, slider_y, slider_w, slider_h)
        # Draw the slider fill
        my_canvas.rect(slider_x, slider_y, slider_fill, slider_h, fill=True)                
        # Draw the mouse cursor
        my_canvas.arrow(x+5, y+10, x, y)
        my_canvas.show()
    
        # Poll the mouse for buttonclicks
        button, position, timestamp = my_mouse.get_click(timeout = 20)
        if button != None:
            break
        
    slider_percent = 100.0*slider_fill/slider_w     
    self.experiment.set("slider_percent", slider_percent)

    There's much bigger issues in the world, I know. But I first have to take care of the world I know.
    cogsci.nl/smathot

  • edited 2:39AM

    That worked beautifully. Thanks again for your help.

  • edited 2:39AM

    This one's great, thanks a bunch! This could be a bit of a silly question, but I'm going to risk making a slight fool of myself: where can I adjust the colours of the text and maybe the background as well? Did I miss it in your code?

    Thanks in advance!

    Edwin

  • edited December 2011

    Hi Edwin,

    You can use either the set_fgcolor() and set_bgcolor() functions, which will affect all subsequent drawing operations, or pass the 'color' keyword for a single drawing operation. So the following (adapted from above) will give you a horribly coloured slider:

    ...
    my_canvas.set_bgcolor('green')
    my_canvas.clear()
    # Draw some text (this can be anything) 
    my_canvas.text("Question goes here", y=slider_y-100, color='blue') 
    my_canvas.set_fgcolor('red')
    my_canvas.text("Click to accept ...", y=slider_y+100) 
    # Draw the slider frame
    my_canvas.rect(slider_x, slider_y, slider_w, slider_h)
    # Draw the slider fill
    my_canvas.rect(slider_x, slider_y, slider_fill, slider_h, fill=True)                
    # Draw the mouse cursor
    my_canvas.arrow(x+5, y+10, x, y)
    my_canvas.show()
    ...

    For a complete list of canvas functions, see this page: http://osdoc.cogsci.nl/python-inline-code/canvas-functions

    Hope this helps!

    Regards,
    Sebastiaan

    There's much bigger issues in the world, I know. But I first have to take care of the world I know.
    cogsci.nl/smathot

  • edited 2:39AM

    Hi Sebastiaan,
    That seems to work, thanks a bunch!

  • Hi,

    i am trying to make a slider working from keyboard keys RIGHT and LEFT, for say.
    I cannot use the mouse as i am in the MRI scanner.
    I dont find any way to distinguish the keyboard presses from their release (to smooth the slider movement).. is there one, somehow ?

    Thanks
    PE

  • Hi,

    This code is just what we were looking for, but it's quite laggy at runtime (a few seconds, the mouse tends to be jumpy). Do you have any hints?

  • You can try different backends. Which one do you use right now?

    Btw. the discussion here is rather old, which code did you use eventually? And did you have to tweak it?

    Eduard

  • edited February 1

    We're using xpyriment as the backend, and here is what we did with the code we're using:

    my_canvas = canvas()
    my_mouse = mouse(timeout=20)
    
    # Set slider dimensions. This assumes that 0,0 is the display center, which is
    # the default in OpenSesame >= 3.
    slider_w = 500
    slider_h = 10
    slider_x = -slider_w/2
    slider_y = -slider_h/2
    
    while True:
    
        # Determine the slider fill based on the mouse position
        pos, time = my_mouse.get_pos()
        x, y = pos
        slider_fill = min(slider_w, max(0, x-slider_x))
    
        my_canvas.clear()
        # Draw some text (this can be anything)
        my_canvas.text("Please rate the text you just read on naturalness", y=slider_y-100) 
        my_canvas.text("Click to accept rating...", y=slider_y+100) 
        my_canvas.text("Most natural", x=slider_x+600)
        my_canvas.text("Least natural", x=slider_x-100)
        # Draw the slider frame
        my_canvas.rect(slider_x, slider_y, slider_w, slider_h)
        # Draw the slider fill
        my_canvas.rect(slider_x, slider_y, slider_fill, slider_h, fill=True)                
        # Draw the mouse cursor
        my_canvas.arrow(x+5, y+10, x, y)
        my_canvas.show()
    
        # Poll the mouse for buttonclicks
        button, position, timestamp = my_mouse.get_click()
        if button is not None:
            break
    
    # Set the slider response as an experimental variable
    var.slider_percent = 100.0*slider_fill/slider_w    
    
  • edited February 8

    Hi,
    Here an optimized version of the slider. Hope it is sufficient.

    my_canvas = canvas()
    my_mouse = mouse(timeout=20)
    my_mouse.show_cursor(True)
    # Set slider dimensions. This assumes that 0,0 is the display center, which is
    # the default in OpenSesame >= 3.
    slider_w = 500
    slider_h = 10
    slider_x = -slider_w/2
    slider_y = -slider_h/2
    my_canvas.text("Please rate the text you just read on naturalness", y=slider_y-100) 
    my_canvas.text("Click to accept rating...", y=slider_y+100) 
    my_canvas.text("Most natural", x=slider_x+600)
    my_canvas.text("Least natural", x=slider_x-100)
    # Draw the slider frame
    my_canvas.rect(slider_x, slider_y, slider_w, slider_h)
    lifeCanvas = canvas()
    while True:
    
        # Determine the slider fill based on the mouse position
        pos, time = my_mouse.get_pos()
        x, y = pos
        slider_fill = min(slider_w, max(0, x-slider_x))
    
        lifeCanvas.clear()
        my_mouse.set_visible()
    
        lifeCanvas.copy(my_canvas)
        # Draw some text (this can be anything)
    
    
        # Draw the slider fill
        lifeCanvas.rect(slider_x, slider_y, slider_fill, slider_h, fill=True)                
        # Draw the mouse cursor
        lifeCanvas.show()
    
        # Poll the mouse for buttonclicks
        button, position, timestamp = my_mouse.get_click()
        if button is not None:
            break
    
    # Set the slider response as an experimental variable
    var.slider_percent = 100.0*slider_fill/slider_w    
    

    Eduard

  • edited April 23

    Hi all,

    I'm doing a mouse tracking experiment (with the Mousetrap plug-in) using the visual analogue scale (slider) based on the code above (by Eduard). Before that I used this code:

    # import everything we need
    from openexp.canvas import canvas
    from openexp.mouse import mouse
    
    # create the instances we need
    my_canvas = canvas(self.experiment)
    my_mouse = mouse(self.experiment, timeout=1)
    
    # slider dimensions
    slider_w = 500
    slider_h = 10
    slider_x = -slider_w/2
    slider_y = -slider_h/2
    
    # draw some text (this can be anything)
    my_canvas.text("To what extent were your thoughts focused on or off the task just before this moment?<br><br>Please indicate a percentage where 100% indicates completely on-task and 0% completely off-task.", y=slider_y-200, font_size=30)
    #draw options
    my_canvas.text("0%<br>(Completely off-task)", y= slider_y+50, x= -250, )
    my_canvas.text("100%<br>(Completely on-task)", y= slider_y+50, x= 250)
    # draw the slider frame
    my_canvas.rect(slider_x, slider_y, slider_w, slider_h)
    # add a text below the bottom slider, telling participants to click to accept
    my_canvas.text("Click your mouse to accept ...", y=slider_y+200) 
    
    # keep showing the interactive slider until a click has been made
    clicked = False
    while not clicked:
    
        # determine the slider fill based on the mouse position
        pos, time = my_mouse.get_pos()
        x, y = pos
        slider_fill = min(slider_w, max(0, x-slider_x))
            # draw an empty rect within the slider frame, effectively resetting it
        my_canvas.rect(slider_x, slider_y, slider_w, slider_h, fill=True, color=self.get("background"))
            # draw the slider fill
        my_canvas.rect(slider_x, slider_y, slider_fill, slider_h, fill=True)
            # show the updated canvas
        my_canvas.show()
        # Poll the mouse for buttonclicks
        button, position, timestamp = my_mouse.get_click(timeout = 1)
        if button != None:
            clicked = True
    
    
    # save the slider's filling
    slider_percent = 100.0*slider_fill/slider_w  
    exp.set("slider_percent", slider_percent)
    

    However, with the code by Eduard, sometimes my stimuli do not show at random trials. When I used the code in this comment this didn't happen and it's the only thing I have changed.

    So the stimuli do not show, but the buttons that I made with the Mousetrap plug-in at the same place of the stimuli are still clickable. The experiment then moves to the next trial and there the stimuli do show.

    I really don't know if this is because of the change in code for the slider, but I hope someone can help me with this.

    Best,

    Dirk

  • There's much bigger issues in the world, I know. But I first have to take care of the world I know.
    cogsci.nl/smathot

Sign In or Register to comment.