psychopy.org | Reference | Downloads | Github

How to take a screenshot in psychopy

Hi,
My computer system is win10, PsychoPy 1.85.6
In my experiment, I need to use the mouse to draw simple lines on the screen, and I hope to take a screenshot to store the drawn lines. Does anyone know how to take screenshots and store them?

thanks
eliza

Hi,

The Window class has a .getMovieFrame() function:

https://www.psychopy.org/api/visual/window.html#psychopy.visual.Window.getMovieFrame

Call that as you need, then at the end of the experiment, call .saveMovieFrames() to save them to files:

https://www.psychopy.org/api/visual/window.html#psychopy.visual.Window.saveMovieFrames

1 Like

Thanks for your timely reply. I tried to modify it according to your method, but I got one picture per frame. Therefore, many pictures were generated, which resulted in program stagnation.

This is my code, the function I want to achieve is to draw some simple shapes with the mouse, and then press the button to go to the next screen, how can I just capture the picture after mouse drawing?
Thanks a lot!

         # test for mouse draw lines
#        t2 = visual.TextStim(win,text=" ",pos=(0,0))
        drawlist = []
        m = event.Mouse(win=win)

        if frameN >= 60:
            while True:
                trial_image1.draw()
                trial_image2.draw()
                for item in drawlist:
                    item.draw()
                win.flip()
                win.getMovieFrame()
                pos = m.getPos().tolist()
                if m.getPressed()[0]==1:
                    # if the mouse is down, determine if JUST pressed, or still pressed
                    if mousedown == False:
                        # start a new drawing phase (and change colors)
                        mousedown = True
                        drawlist.append(visual.ShapeStim(win,lineWidth=2.0,lineColor='red',closeShape=False))
                        drawlist[-1].setVertices(pos)
                    else:
                        # continue last drawing phase
                        if len(drawlist[-1].vertices.shape)==1:
                            # only one vertex thus far (vertices is 1D)
                            drawlist[-1].setVertices([drawlist[-1].vertices.tolist()]+[pos])
                        else:
                            # more than one vertex (vertices is 2D)
                            drawlist[-1].setVertices(drawlist[-1].vertices.tolist()+[pos])
                elif m.getPressed()[0]==0:
                    # if the mouse is up, reset and wait for new drawing phase
                    mousedown = False
                    win.saveMovieFrames('1.png') 
                if m.getPressed()[2]:
                    # if right button is pressed, quit early
                    break
                
                 # *trial_resp* updates    
                if t >= 0.0 and trial_resp.status == NOT_STARTED:
                    # keep track of start time/frame for later
                    trial_resp.tStart = t
                    trial_resp.frameNStart = frameN  # exact frame index
                    trial_resp.status = STARTED
                    # keyboard checking is just starting
                    win.callOnFlip(trial_resp.clock.reset)  # t=0 on next screen flip
                    event.clearEvents(eventType='keyboard')
                if trial_resp.status == STARTED:
                    theseKeys = event.getKeys(keyList=['space'])
                    
                    # check for quit:
                    if "escape" in theseKeys:
                        endExpNow = True
                    if len(theseKeys) > 0:  # at least one key was pressed
                        trial_resp.keys = theseKeys[-1]  # just the last key pressed
                        trial_resp.rt = trial_resp.clock.getTime()
                        # a response ends the routine
                        
                        continueRoutine = False
                        
                        break	   
                       
        # *trial_resp* updates
        if frameN >= 60 and trial_resp.status == NOT_STARTED:
            # keep track of start time/frame for later
            trial_resp.tStart = t
            trial_resp.frameNStart = frameN  # exact frame index
            trial_resp.status = STARTED
            # keyboard checking is just starting
            win.callOnFlip(trial_resp.clock.reset)  # t=0 on next screen flip
            event.clearEvents(eventType='keyboard')
        if trial_resp.status == STARTED:
            theseKeys = event.getKeys(keyList=['space'])
            
            # check for quit:
            if "escape" in theseKeys:
                endExpNow = True
            if len(theseKeys) > 0:  # at least one key was pressed
                trial_resp.keys = theseKeys[-1]  # just the last key pressed
                trial_resp.rt = trial_resp.clock.getTime()
                # a response ends the routine
                continueRoutine = False

Just call both of those functions once, at the end of the trial when the drawing is completed, rather than saving an image on every screen refresh (which will capture the drawing incrementally).

According to your suggestion, add a button response, the problem is solved, thank you very much!