Pmw.Counter() - entry field with up and down arrow buttons
This class consists of an entry field with arrow buttons to increment and decrement the value in the entry field. Standard counting types include numbers, times and dates. A user defined counting function may also be supplied for specialised counting. Counting can be used in combination with the entry field's validation. The components may be laid out horizontally or vertically.
Each time an arrow button is pressed the value displayed in the entry field is incremented or decremented by the value of the increment option. If the new value is invalid (according to the entry field's validate option, perhaps due to exceeding minimum or maximum limits), the old value is restored.
When an arrow button is pressed and the value displayed is not an exact multiple of the increment, it is "truncated" up or down to the nearest increment.
The most general way to specify the datatype option is as a dictionary. The kind of counting is specified by the 'counter' dictionary field, which may be either a function or the name of one of the standard counters described below. The default is 'numeric'.
Any other fields in the dictionary are passed on to the counter function as keyword arguments.
If datatype is not a dictionary, then it is equivalent to
specifying it as a dictionary with a single 'counter' field.
For example, datatype = 'real'
is equivalent to
datatype = {'counter' : 'real'}
.
The standard counters are:
string.atol()
.
string.atof()
. This
counter accepts a 'separator' argument, which specifies
the charactor used to represent the decimal point. The
default 'separator' is '.'.
Pmw.timestringtoseconds()
. This counter accepts a
'separator' argument, which specifies the charactor used to
separate the time fields. The default separator is ':'.
Pmw.datestringtojdn()
. This counter accepts a 'separator'
argument, which specifies the charactor used to separate the
three date fields. The default is '/'. This counter also
accepts a 'format' argument, which is passed to
Pmw.datestringtojdn()
to specify the desired ordering of the
fields. The default is 'ymd'.
If 'counter' is a function, then it will be called whenever the counter is incremented or decremented. The function is called with at least three arguments, the first three being (text, factor, increment), where text is the current contents of the entry field, factor is 1 when incrementing or -1 when decrementing, and increment is the value of the increment megawidget option.
The other arguments are keyword arguments made up of the fields of the datatype dictionary (excluding the 'counter' field).
The counter function should return a string representing the incremented or decremented value. It should raise a a ValueError exception if the text is invalid. In this case the bell is rung and the entry text is is not changed.
The default for datatype is numeric.
For the number datatypes, the value of increment is a number. For the 'time' datatype, the value is in seconds. For the 'date' datatype, the value is in days. The default is 1.
If None, a label component is not created. The default is None.
class Demo: def __init__(self, parent): # Need to use long ints here because on the Macintosh the maximum size # of an integer is smaller than the value returned by time.time(). now = (long(time.time()) / 300) * 300 # Create the Counters. self._date = Pmw.Counter(parent, labelpos = 'w', label_text = 'Date (4-digit year):', entryfield_value = time.strftime('%d/%m/%Y', time.localtime(now)), entryfield_command = self.execute, entryfield_validate = {'validator' : 'date', 'format' : 'dmy'}, datatype = {'counter' : 'date', 'format' : 'dmy', 'yyyy' : 1}) self._isodate = Pmw.Counter(parent, labelpos = 'w', label_text = 'ISO-Date (4-digit year):', entryfield_value = time.strftime('%Y-%m-%d', time.localtime(now)), entryfield_command = self.execute, entryfield_validate = {'validator' : 'date', 'format' : 'ymd', 'separator' : '-' }, datatype = {'counter' : 'date', 'format' : 'ymd', 'yyyy' : 1, 'separator' : '-' }) self._time = Pmw.Counter(parent, labelpos = 'w', label_text = 'Time:', entryfield_value = time.strftime('%H:%M:%S', time.localtime(now)), entryfield_validate = {'validator' : 'time', 'min' : '00:00:00', 'max' : '23:59:59', 'minstrict' : 0, 'maxstrict' : 0}, datatype = {'counter' : 'time', 'time24' : 1}, increment=5*60) self._real = Pmw.Counter(parent, labelpos = 'w', label_text = 'Real (with comma):', entryfield_value = '1,5', datatype = {'counter' : 'real', 'separator' : ','}, entryfield_validate = {'validator' : 'real', 'min' : '-2,0', 'max' : '5,0', 'separator' : ','}, increment = 0.1) self._custom = Pmw.Counter(parent, labelpos = 'w', label_text = 'Custom:', entryfield_value = specialword[:4], datatype = _custom_counter, entryfield_validate = _custom_validate) self._int = Pmw.Counter(parent, labelpos = 'w', label_text = 'Vertical integer:', orient = 'vertical', entry_width = 2, entryfield_value = 50, entryfield_validate = {'validator' : 'integer', 'min' : 0, 'max' : 99} ) counters = (self._date, self._isodate, self._time, self._real, self._custom) Pmw.alignlabels(counters) # Pack them all. for counter in counters: counter.pack(fill='x', expand=1, padx=10, pady=5) self._int.pack(padx=10, pady=5) def execute(self): print 'Return pressed, value is', self._date.get() specialword = 'Monti Python ik den Holie Grailen (Bok)' def _custom_validate(text): if string.find(specialword, text) == 0: return 1 else: return -1 def _custom_counter(text, factor, increment): # increment is ignored here. if string.find(specialword, text) == 0: length = len(text) if factor == 1: if length >= len(specialword): raise ValueError, 'maximum length reached' return specialword[:length + 1] else: if length == 0: raise ValueError, 'empty string' return specialword[:length - 1] else: raise ValueError, 'bad string ' + text
Home.
Pmw 0.8.5
Maintainer
gregm@iname.com.
9 Feb 2001
Manual page last reviewed: 24 May 1998