psychopy.org | Reference | Downloads | Github

Drag & Drop Stimuli

Hi everyone!

I’ll start by saying I’m almost completely new to PsychoPy (and absolutely new to Python).

I’d like to know whether what I’m trying to achieve is possible using Builder (without adding code).

I would like to present several pictures horizontally in a pseudorandom order on the upper part of the screen (so far, I can easily do!).

Then, I would like the participant to be able to drag each of these pictures and order them vertically on the lower part of the screen, where they will fit into pre-existing empty “boxes” (which I think should also be images).

Is this at all possible (without adding code)?

I’ll most likely tackle this one way or another - I’d just like to know how much studying I have ahead of me before I do.

Thanks!
Ezekiel

1 Like

Hi @EzekielS, it is possible with minimal coding required. You need to add your images, a mouse and a code component for controlling your image positions. You would do something like the following:

# Begin Routine
myPics = [pic1, pic2, pic3]  # You image components

# Each Frame
for pic in myPics:                # for each pic
    if mouse.isPressedIn(pic):    # If the picture is currently clicked
        pic.pos = mouse.getPos()  # set pic position to mouse position - drag and drop

We can also add code to detect whether the pictures are in the correct position. If you need this, get familiar with this stage first, and then let me know what makes a correct response.

1 Like

Hey @dvbridges!

Much appreciated! I’ll start tinkering and see where it goes, though I don’t doubt I’ll be back with questions.

@dvbridges

This worked perfectly, thank you!

I’ve noticed that when dragging one of the images, if I pass over another image, I’m now dragging both of them. Is there a way to add a condition before the drag and drop code that checks if I’m already dragging? All of the images are the same size so when accidentally dragging more than one, the others would get “lost”.

Yes, you would need to create a function, which knows when an image is currently being moved. It gets more complicated when dealing with this, but I already have a solution. It works by passing back and forth the name of the currently clicked piece, and the move function works only for that piece if it exists.

# Begin Experiment
def movePicked(picked, mouse, grabbed):
    # Move piece if we already moving that piece
    if grabbed is not None and mouse.isPressedIn(grabbed):
        grabbed.pos = mouse.getPos()
        return grabbed
    else:
        # Move newly clicked piece
        for piece in picked:
            if mouse.isPressedIn(piece) and grabbed is None:
                return piece

# Begin Routine
pieces = [pic1, pic2, pic3]
picked = []
movingPiece = None

# Each Frame
for piece in pieces:
    if mouse.isPressedIn(piece) and movingPiece is None:
        picked.append(piece)

movingPiece = movePicked(picked, mouse, movingPiece)

Here is a working example…
movingPics.psyexp (11.0 KB)

Again, this works great!

As per your earlier comment…

There would not be a correct response per se. Participants will be placing the pictures vertically, thus creating a ranking. What I’m looking for is the ranking of the images (where each image corresponds to a different experimental condition).

So eventually, what I’m hoping to get as output is - img1(condition x) in first position, img2(condition y) in second position, etc…