# Form Component coding in pycharm

Does anyone know if there is any possible way to implement Form Component or similar when coding in pycharm and not in the builder?

thank you very very much!

@galaharon, if you add a Form component to Builder and compile the Python code, then you can ooen the .py file in Pycharm and see how to create and draw a Form component.

thank you very much!
do you know if it possible to write in Hebrew?

Sorry I don’t know , you could try. Also, @Michael may know about presenting Hebrew using Form, which is essentially presenting many TextStim components.

@Michael it’s written LTR instead of RTL
(also the text, and also the whole form - I would like the questions to be on the right and the answers on the left)

Thank you!!

Great, btw swapping the position of the items on the x-axis can be done using code. In the “begin routine” tab of a code component:

for item in yourForm.items:
item['responseCtrl'].pos = list(item['responseCtrl'].pos)
item['itemCtrl'].pos = list(item['itemCtrl'].pos)
item['responseCtrl'].pos[0], item['itemCtrl'].pos[0] = item['itemCtrl'].pos[0], item['responseCtrl'].pos[0]


thank you!!!
what is the item name for the response answers (not the “responseCtrl”
because this doesn’t move

@dvbridges
this is a better image explaining

the problem

for item in TIPI_form.items:
item['responseCtrl'].pos, item['itemCtrl'].pos = item['itemCtrl'].pos, item['responseCtrl'].pos
# If the response slider is too far left, use below code
sliderOffset = .3
item['responseCtrl'].pos = [item['responseCtrl'].pos[0]+sliderOffset, item['responseCtrl'].pos[1]]



@galaharon try the above instead. Also, you can change the size of your item and response sliders using itemWidth and responseWidth values for each item in your spreadsheet.

sorry but i have another question - I have this code to end the survey once all the questions have been answered but it is not ending. (it seems like there are more questions that are supposed to be but there are not - I’m attaching a picture):

    if BFI.status == NOT_STARTED and tThisFlip >= 0.0 - frameTolerance:
# keep track of start time/frame for later
BFI.frameNStart = frameN  # exact frame index
BFI.tStart = t  # local t and not account for scr refresh
BFI.tStartRefresh = tThisFlipGlobal  # on global time
win.timeOnFlip(BFI, 'tStartRefresh')  # time at next scr refresh
BFI.setAutoDraw(True)

# check for quit (typically the Esc key)
if endExpNow or defaultKeyboard.getKeys(keyList=["escape"]):
core.quit()

# check if all components have finished
if not continueRoutine:  # a component has requested a forced-end of Routine
break
continueRoutine = False  # will revert to True if at least one component still running
for thisComponent in trialComponents:
if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
continueRoutine = True
break  # at least one component has not yet finished

# refresh the screen
if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
win.flip()

# -------Ending Routine "trial"-------
for thisComponent in trialComponents:
if hasattr(thisComponent, "setAutoDraw"):
thisComponent.setAutoDraw(False)
BFI.autodraw = False
# the Routine "trial" was not non-slip safe, so reset the non-slip timer
routineTimer.reset()

# Flip one final time so any remaining win.callOnFlip()
# and win.timeOnFlip() tasks get executed before quitting
win.flip()


In the “Each Frame” tab, add the following:

if bfi.complete:
continueRoutine = False


Alternatively, you could add a a continue button that activates only when the Form is complete. For this, see the BigFive Demo in Builder.

thank you!!

Hi @dvbridges ! i think this will be my last question using the form component
I managed to write in Hebrew by reversing the order of the characters

BUT for some unknown reason each run the questions are displayed differently - Hebrew (the way it need to be every run), or small boxes. It seems the problem is only in windows.
do you have any thoughts that can maybe help me?

my code is:

    # ------Prepare to start Routine "trial"-------
original_allowStencil = win.allowStencil
win.allowStencil = True

BFI = visual.Form(
win=win, name='BFI',
items='bigFiveItems1.xlsx',
textHeight=0.04,
randomize=False,
size=(1.7, 0.7),
pos=(0, 0),
style=('dark',),
)

# update component parameters for each repeat
# keep track of which components have finished
trialComponents = [BFI]
for thisComponent in trialComponents:
thisComponent.tStart = None
thisComponent.tStop = None
thisComponent.tStartRefresh = None
thisComponent.tStopRefresh = None
if hasattr(thisComponent, 'status'):
thisComponent.status = NOT_STARTED

# reset timers
_timeToFirstFrame = win.getFutureFlipTime(clock="now")
trialClock.reset(-_timeToFirstFrame)  # t0 is time of first possible flip
frameN = -1

# change components from right to left
for item in BFI.items:
item['itemCtrl'].pos, item['responseCtrl'].pos = item['responseCtrl'].pos, item['itemCtrl'].pos
# If the response slider is too far left, use below code
sliderOffset = .7
item['responseCtrl'].pos = [item['responseCtrl'].pos[0] + sliderOffset, item['responseCtrl'].pos[1]]

# Reverse text
item['itemCtrl'].text = item['itemCtrl'].text[::-1]
for label in item['responseCtrl'].labelObjs:
label.text = label.text[::-1]

# -------Run Routine "trial"-------
continueRoutine = True
while continueRoutine:
# # get current time
t = trialClock.getTime()
tThisFlip = win.getFutureFlipTime(clock=trialClock)
tThisFlipGlobal = win.getFutureFlipTime(clock=None)
frameN = frameN + 1  # number of completed frames (so 0 is the first frame)

# # update/draw components on each frame
#
if BFI.status == NOT_STARTED and tThisFlip >= 0.0 - frameTolerance:
# keep track of start time/frame for later
BFI.frameNStart = frameN  # exact frame index
BFI.tStart = t  # local t and not account for scr refresh
BFI.tStartRefresh = tThisFlipGlobal  # on global time
win.timeOnFlip(BFI, 'tStartRefresh')  # time at next scr refresh
BFI.setAutoDraw(True)

# check for quit (typically the Esc key)
if kb.getKeys(keyList=["escape"]):
core.quit()
return

# check if all components have finished
if not continueRoutine:  # a component has requested a forced-end of Routine
break
continueRoutine = False  # will revert to True if at least one component still running
for thisComponent in trialComponents:
if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
continueRoutine = True
break  # at least one component has not yet finished

# refresh the screen
if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
win.flip()

# end if all questions were answered:
if BFI.complete:
continueRoutine = False

BFI_rawdata = BFI.getData()

# Cleanup
for thisComponent in trialComponents:
if hasattr(thisComponent, "setAutoDraw"):
thisComponent.setAutoDraw(False)
BFI.autodraw = False
win.allowStencil = original_allowStencil
win.flip()


and I get this error in all times (although it is running):
Exception ignored in: <function ImageStim.del at 0x0000020394085488>
Traceback (most recent call last):
File “C:\Users\schec\PycharmProjects\Reward_Effort_experiment\venv\lib\site-packages\psychopy\visual\image.py”, line 239, in del
File “C:\Users\schec\PycharmProjects\Reward_Effort_experiment\venv\lib\site-packages\pyglet\gl\lib.py”, line 99, in errcheck
TypeError: ‘NoneType’ object is not callable
Exception ignored in: <function TextStim.del at 0x000002039411A400>
Traceback (most recent call last):
File “C:\Users\schec\PycharmProjects\Reward_Effort_experiment\venv\lib\site-packages\psychopy\visual\text.py”, line 240, in del
File “C:\Users\schec\PycharmProjects\Reward_Effort_experiment\venv\lib\site-packages\pyglet\gl\lib.py”, line 99, in errcheck
TypeError: ‘NoneType’ object is not callable
Exception ignored in: <function TextStim.del at 0x000002039411A400>
Traceback (most recent call last):
File “C:\Users\schec\PycharmProjects\Reward_Effort_experiment\venv\lib\site-packages\psychopy\visual\text.py”, line 240, in del
File “C:\Users\schec\PycharmProjects\Reward_Effort_experiment\venv\lib\site-packages\pyglet\gl\lib.py”, line 99, in errcheck
TypeError: ‘NoneType’ object is not callable
thank you!!

Oh, do you have any rows in your Form file that only contain text? I.e., text with no response slider?

gal.xlsx (13.0 KB)
no. it looks like this

@galaharon , for some reason the Textbox2 used in Forms does not support Hebrew letters. It looks like the text shows up on the sliders (radio buttons) because Sliders use TextStim to present text. Do you plan on presenting this task online?

Regarding the error above, do you have any images presented in your task?

I’m not planning on presenting it online. is there a way to work around it?

no, I have no images, just the form questions on the screen and that’s all.

First, try setting the version to PsychoPy 2020.1.3 and running the task, as this version does not implement TextBox2. If that fails, please let me know the version of PsychoPy you are using and I can send you a modified Form component which uses TextStim in place of TextBox2.

for some reason i don’t have this version. another version maybe?

I would attempt this from the Builder interface. Oh, you can also use any of the 2020.1 versions.