See also: the discussion on SourceForge about this very topic.
Update: I just noticed another post on the SourceForge forum that looks like it deals with freetext typing, but I haven't tried Aaron's solution.
#!/usr/bin/python
from pyepl.locals import *
from pyepl import timing, display, keyboard, exputils
import string
##############################
def textBox(clk=None,
keys=None,
time_limit=None,
disptxt='',
wordHeight=None,
showProportional=(.5,.5)):
"""
Allows freeform text entry, including BACKSPACE, until
RETURN or ENTER are pressed. Allows you to define your
own set of allowed keys and a time limit.
CLK = a PresentationClock
KEYS = a list of keys (as strings) that will
register. All other keys will be ignored. Defaults to
just the lowercase keys, plus RETURN/ENTER, BACKSPACE
and SPACE. To define your own, follow this example:
keys = list(string.lowercase) + ['RETURN','ENTER','BACKSPACE','SPACE']
N.B. Make sure to include at least RETURN or ENTER,
since textBox is hardcoded to wait for one of those
keys to end text entry.
TIME_LIMIT
DISPTXT = this will be displayed until the user types
the first key, after which it will be replaced with
whatever they type
[Based on the pyepl/convenience.py/mathDistract function.]
todo:
- it should log every keypress with a timestamp, in case
you want to do some kind of crazy RT analysis. For
now, i think it's probably somewhere buried in the
KeyTrack.
"""
# get the tracks
v = display.VideoTrack.lastInstance()
k = keyboard.KeyTrack.lastInstance()
if clk is None: clk = exputils.PresentationClock()
# we only need to calculate the END_TIME (i.e. the
# time we're going to stop) if we have a time limit
if time_limit: end_time = timing.now() + time_limit
if keys is None:
keys = list(string.lowercase) + ['RETURN','ENTER','BACKSPACE','SPACE']
ans_but = k.keyChooser(*keys)
# show the DISPTXT that will be replaced after the first keypress
# rt = v.showCentered(Text(disptxt,size=wordHeight))
rt = v.showProportional(Text(disptxt,size=wordHeight),
showProportional[0],showProportional[1])
v.updateScreen(clk)
# wait for keypress
kret,timestamp = ans_but.waitWithTime(maxDuration=time_limit, clock=clk)
# throw away the starting text, and get ready to display
# whatever the user typed
disptxt = ''
while kret and (kret.name != "RETURN" and kret.name != "ENTER"):
# process the response
if kret.name == 'BACKSPACE':
# remove last char
if len(disptxt) > 0:
disptxt = disptxt[:-1]
elif kret.name == 'RETURN' or kret.name == 'ENTER':
pass
elif kret.name == 'SPACE':
disptxt = disptxt + ' '
else:
# just append it
disptxt = disptxt + kret.name
# update the text - we need to do it in two
# steps rather than with replace, because
# replace doesn't re-center it
# rt = v.replace(rt,Text(disptxt))
v.unshow(rt)
rt = v.showProportional(Text(disptxt,size=wordHeight),
showProportional[0],showProportional[1])
v.updateScreen(clk)
# wait for another response
if time_limit: time_limit = end_time - timing.now()
kret,timestamp = ans_but.waitWithTime(maxDuration=time_limit,clock=clk)
# print 'You typed: ' + disptxt
return disptxt
No comments:
Post a Comment