I'm new to python and PsychoPy. I want to draw a window and show my instructions for a task. If spacebar is pressed, the next instruction is supposed to show.
I tried it without using a class but I would like to stick to object-oriented programming.
from psychopy import visual, core, event
winsize=[1536, 864]
mywin = visual.Window(winsize, monitor='testMonitor', units='deg',allowGUI=False, winType='pyglet',fullscr=True, color = 'dimgrey',colorSpace ='rgb')
class textstim():
def __init__(self, win, txt='Unicorn'):
self.window = win
self.text = visual.TextStim(win, text=txt, font=['Gill Sans MT', 'Arial','Helvetica','Verdana'], pos=[winsize[0]/4,winsize[1]/4], units='deg', alignHoriz='left', wrapWidth=winsize[0]/2, alignVert='top', height=1.0, color='gainsboro')
def settext(self, txt):
self.text.setText(text=txt)
def show_until_spacebar(self):
while True:
self.text.draw()
self.window.flip()
if event.getKeys(['space']):
break
welcome = textstim(mywin)
welcome.settext("Hello!\n\n"
"Thank you for participating!")
welcome.show_until_spacebar()
With my code I'm opening a window and when I hit space it closes again, but there is no text to be seen.
I suspect the non-appearance of your text may simply be due to a units inconsistency. You have defined the units for the text stimulus to be in degrees, yet you calculate its position based upon the variable winsize
, which is in pixels. I suspect the stimulus is being drawn, but it is massively offscreen (i.e. something like 1536/4 deg
off to the right of centre and 864/4 deg
above centre).
But at a higher level, you might want to give more though to your OOP design here. e.g., the init
and settext
methods of your textstim
class just duplicate existing behaviour of the underlying TextStim
class. So you could just add your new show_until_spacebar
functionality to TextStim
and be done with it, without all of that overhead. The fact that the two classes effectively have the same name indicates that there is some duplication going on (and as a result you've been forced to abandon the convention of naming classes with an initial capital, to avoid a conflict).
But regardless, you then perhaps need to consider whether the show_until_spacebar()
functionality belongs in an individual stimulus class, or other more properly it should be added as a function to the Window
class.
i.e. what happens if you want this functionality to exist for another sort of stimulus? Do you repeat yourself and add the same function to that class, or do you create a base superclass that they both inherit from? But even that is limiting. e.g. what happens if you want this functionality to exist for a window with multiple stimuli? It seems messy to call the function on only one of them.
That indicates that the function should probably reside in the Window
class. There, it only needs to be defined once, and it can simply cycle through drawing all of the stimuli attached to it, and wait for the space bar. That way, it works cleanly, regardless of whether there it contains just a single text stimulus, or many others, and you then have a much more flexible function that can be used in other situations.
Good luck with whatever route you take: it is nice seeing someone consciously adopt an object-oriented approach to PsychoPy code. Being designed for non-programmers, it can more easily be used in a simple procedural way, but an object-oriented approach leads to more cognitive discipline on your part and hopefully much cleaner and more readable code. But if does require quite a bit of thought and preparation beforehand: if one hasn't properly conceptualised how the various classes will interact over the course of an experiment, you can end up backed into a corner due to an inflexible class system.