psychopy.org | Reference | Downloads | Github

Stop showing an image

Hi!

I’m building this experiment in which the participants can build an unlimited number of barriers in a 20x10 grid. Based on the participants inputs, the barriers positions are included in a Barrier_list in the End Routine tab of a code component:

if ... #participants correct responses:
    barrier_pos = [datetime.datetime.now(), copy.deepcopy(Subject_position)]
    Barrier_list.append(barrier_pos)

and in Begin Routine the following code draw the barriers in the screen based on their positions:

for Barrier_position in list(Barrier_list):
    Barrier = visual.Rect(
        win=win, name='Barrier',units='pix',
        width=(49.5, 49.5)[0], height=(49.5, 49.5)[1],
        ori=0, pos=Barrier_position[1],
        lineWidth=0, lineColor='black', lineColorSpace='rgb',
        fillColor=u'black', fillColorSpace='rgb',
        opacity=1, depth=-5.0, interpolate=True)
    Barrier.setAutoDraw(True)

Ten seconds after being appended to the list, each barrier is removed from it using the timestamp that goes with the position in the code inserted in the Each Frame tab:

for barr in list(Barrier_list):
    datetime.datetime.now()
    if barr[0] <= (datetime.datetime.now() - datetime.timedelta(seconds=10)):
        Barrier_list.remove(barr)
        Barrier.setAutoDraw(False)

Printing Barrier_list shows me that the Ask to print Barrier_list shows me that the [timestamp, [positions]] are being appropriately appended to the list and removed after 10 seconds and the Barriers images are also being drawn in the correct positions. However, when the element [timestamp, [positions]] element is removed from Barrier_list, their images persist on the screen.

Why would this be happening and what can I do to make their images disappear when I remove them form the list?

Thanks and best regards,

Felipe

  • I don’t know what Barrier represents, but you are telling that not to autodraw, rather than barr, which is what you are removing from the list. This is likely why your objects keep drawing. You need to tell the correct object to stop drawing.
  • the line datetime.datetime.now() does nothing.
  • Strongly suggest you don’t use copy.deepcopy(). Why don’t you just do something like this:
barrier_pos = [datetime.datetime.now(), Subject_position[0], Subject_position[1]]

Thanks, Michael.

The alternative to copy.deepcopy() worked well and deleting datetime.datetime.now() too, thanks!

Barrier represent the black squares in the attached screenshot. Each is created when the participant presses “r” 6 times in average.

How could I "tag’ each barrier created to tell which one is to stop drawing?

Best,

Felipe

OK, I missed the code above where you define the barrier objects as a visual.Rect.

What you should do is create the barrier visual representation at the same time as you define the barrier position, and store them all together. Rather than Barrier_list being a list of lists, you should make it a list of dictionaries. These are much more convenient in terms of being able to refer to entries by name.

e.g.

# define a barrier as a dictionary with a number of 
# named attributes:
barrier = {'time': datetime.datetime.now(),
            'x': Subject_position[0], 
            'y': Subject_position[1], 
            'rect': visual.Rect(etc etc)}

barrier['rect'].setAutoDraw(True) # see how we can access a specific aspect of the barrier object
Barrier_list.append(barrier) # and store the whole lot together in one list entry

i.e. you shouldn’t think of the barrier as being the visual representation of it (the rectangle). It is actually a set of attributes. Making it a dictionary allows you to store those various attributes as a whole: you don’t have to worry now about coordinating attributes of the barrier that are currently being stored in separate lists.

It worked!
Thanks so much!

Best,

Felipe

Michael
November 7
OK, I missed the code above where you define the barrier objects as a visual.Rect.

What you should do is create the barrier visual representation at the same time as you define the barrier position, and store them all together. Rather than Barrier_list being a list of lists, you should make it a list of dictionaries. These are much more convenient in terms of being able to refer to entries by name.

e.g.

> # define a barrier as a dictionary with a number of # named attributes:
> barrier = {'time': datetime.datetime.now(), 'x': Subject_position[0], 'y': Subject_position[1], 'rect': visual.Rect(etc etc)} barrier['rect'].setAutoDraw(True) # see how we can access a specific aspect of the barrier object
> Barrier_list.append(barrier) # and store the whole lot together in one list entry