Howdy, Stranger!

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

Supported by

Mixing psychopy and Canvas elements

Is there a straightforward way to display PsychoPy stimuli and Canvas elements on the same screen? i.e., to have the green wedge and fixation dot share a screen in the following example.


wedgeGreen = visual.Pie(win,radius = 100, fillColor = [-1,1,-1],start = 0,end = 90)
wedgeGreen.draw()

my_canvas = Canvas()
my_canvas['my_fixdot'] = FixDot()

win.flip()
my_canvas.show()

key, end_time = my_keyboard.get_key()

Comments

  • Hi @mattm ,

    Yes, that's possible, although it requires a bit of a hack (and thus may break in future releases of OpenSesame). The trick is to implement your own class that a sketchpad can use as an element, and assign a custom value to the _stim property.

    Like so:

    from openexp._canvas._element.psycho import PsychoElement
    from openexp._canvas._element.element import Element
    from psychopy.visual import Pie
    
    
    class CustomElement(PsychoElement, Element):  
    
        def prepare(self):
          
            self._stim = Pie(win,radius=100, fillColor=[-1, 1, -1 ], start=0, end=90)
    
    
    c = Canvas()
    c['my_custom_element'] = CustomElement(c)
    c.show()
    

    Hope this helps!

    — Sebastiaan

  • Many thanks, I will use it carefully!

  • I don't suppose there is a straightforward way to make _stim a compound stimulus, my task is to combine multiple Pie objects into a kind of gauge thing for RT feedback. Of course I could make a separate object for each wedge, but it is not very graceful :]

  • Hi @mattm , there is, actually. You'd just need to also override the show() method as well 😀

    from openexp._canvas._element.psycho import PsychoElement
    from openexp._canvas._element.element import Element
    from psychopy.visual import Pie
    
    
    class CustomElement(PsychoElement, Element):  
    
        def prepare(self):
            self._stim = [
                Pie(win, radius=100, fillColor=[-1, 1, -1 ], start=0, end=90),
                Pie(win, radius=100, fillColor=[1, -1, -1 ], start=180, end=270),
            ]
          
        def show(self):      
            if self.visible:
                for stim in self._stim:
                    stim.draw()
    
    
    c = Canvas()
    c['my_custom_element'] = CustomElement(c)
    c.show()
    


  • edited July 2021

    Fantastic! Is there a straightforward way to pass it arguments (e.g., radius)? I suspect more overriding.

  • @mattm Yes, exactly. You'd need to override __init__() as well. (It might be an idea to implement a more general solution for this, i.e. a way to easily create custom Canvas elements in a non-hacky way. I'll give that some thought.)

    from openexp._canvas._element.psycho import PsychoElement
    from openexp._canvas._element.element import Element
    from psychopy.visual import Pie
    
    class CustomElement(PsychoElement, Element):  
    
        def __init__(self, canvas, radius1=100, radius2=100):
           
            self._radius1 = radius1
            self._radius2 = radius2
            super().__init__(canvas)
    
        def prepare(self):
    
            self._stim = [
                Pie(win, radius=self._radius1, fillColor=[-1, 1, -1 ], start=0, end=90),
                Pie(win, radius=self._radius2, fillColor=[1, -1, -1 ], start=180, end=270)
            ]
    
        def show(self):      
    
            if self.visible:
                for stim in self._stim:
                    stim.draw()
    
    
    c = Canvas()
    c['my_custom_element'] = CustomElement(c, radius1=50, radius2=150)
    c.show()
    
Sign In or Register to comment.