Support siPrefix with no suffix in SpinBox
This commit is contained in:
parent
66c77118dc
commit
cd10719837
@ -31,6 +31,8 @@ spins = [
|
|||||||
pg.SpinBox(value=1.0, suffix='V', siPrefix=True, dec=True, step=0.5, minStep=0.01)),
|
pg.SpinBox(value=1.0, suffix='V', siPrefix=True, dec=True, step=0.5, minStep=0.01)),
|
||||||
("Float with SI-prefixed units,<br>dec step=1.0, minStep=0.001",
|
("Float with SI-prefixed units,<br>dec step=1.0, minStep=0.001",
|
||||||
pg.SpinBox(value=1.0, suffix='V', siPrefix=True, dec=True, step=1.0, minStep=0.001)),
|
pg.SpinBox(value=1.0, suffix='V', siPrefix=True, dec=True, step=1.0, minStep=0.001)),
|
||||||
|
("Float with SI prefix but no suffix",
|
||||||
|
pg.SpinBox(value=1e9, siPrefix=True)),
|
||||||
("Float with custom formatting",
|
("Float with custom formatting",
|
||||||
pg.SpinBox(value=23.07, format='${value:0.02f}',
|
pg.SpinBox(value=23.07, format='${value:0.02f}',
|
||||||
regex='\$?(?P<number>(-?\d+(\.\d+)?)|(-?\.\d+))$')),
|
regex='\$?(?P<number>(-?\d+(\.\d+)?)|(-?\.\d+))$')),
|
||||||
|
@ -119,10 +119,27 @@ def siFormat(x, precision=3, suffix='', space=True, error=None, minVal=1e-25, al
|
|||||||
|
|
||||||
def siParse(s, regex=FLOAT_REGEX, suffix=None):
|
def siParse(s, regex=FLOAT_REGEX, suffix=None):
|
||||||
"""Convert a value written in SI notation to a tuple (number, si_prefix, suffix).
|
"""Convert a value written in SI notation to a tuple (number, si_prefix, suffix).
|
||||||
|
|
||||||
Example::
|
Example::
|
||||||
|
|
||||||
siParse('100 μV") # returns ('100', 'μ', 'V')
|
siParse('100 µV") # returns ('100', 'µ', 'V')
|
||||||
|
|
||||||
|
Note that in the above example, the µ symbol is the "micro sign" (UTF-8
|
||||||
|
0xC2B5), as opposed to the Greek letter mu (UTF-8 0xCEBC).
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
s : str
|
||||||
|
The string to parse.
|
||||||
|
regex : re.Pattern, optional
|
||||||
|
Compiled regular expression object for parsing. The default is a
|
||||||
|
general-purpose regex for parsing floating point expressions,
|
||||||
|
potentially containing an SI prefix and a suffix.
|
||||||
|
suffix : str, optional
|
||||||
|
Suffix to check for in ``s``. The default (None) indicates there may or
|
||||||
|
may not be a suffix contained in the string and it is returned if
|
||||||
|
found. An empty string ``""`` is handled differently: if the string
|
||||||
|
contains a suffix, it is discarded.
|
||||||
"""
|
"""
|
||||||
s = asUnicode(s)
|
s = asUnicode(s)
|
||||||
s = s.strip()
|
s = s.strip()
|
||||||
@ -130,15 +147,20 @@ def siParse(s, regex=FLOAT_REGEX, suffix=None):
|
|||||||
if s[-len(suffix):] != suffix:
|
if s[-len(suffix):] != suffix:
|
||||||
raise ValueError("String '%s' does not have the expected suffix '%s'" % (s, suffix))
|
raise ValueError("String '%s' does not have the expected suffix '%s'" % (s, suffix))
|
||||||
s = s[:-len(suffix)] + 'X' # add a fake suffix so the regex still picks up the si prefix
|
s = s[:-len(suffix)] + 'X' # add a fake suffix so the regex still picks up the si prefix
|
||||||
|
|
||||||
|
# special case: discard any extra characters if suffix is explicitly empty
|
||||||
|
if suffix == "":
|
||||||
|
s += 'X'
|
||||||
|
|
||||||
m = regex.match(s)
|
m = regex.match(s)
|
||||||
if m is None:
|
if m is None:
|
||||||
raise ValueError('Cannot parse number "%s"' % s)
|
raise ValueError('Cannot parse number "%s"' % s)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sip = m.group('siPrefix')
|
sip = m.group('siPrefix')
|
||||||
except IndexError:
|
except IndexError:
|
||||||
sip = ''
|
sip = ''
|
||||||
|
|
||||||
if suffix is None:
|
if suffix is None:
|
||||||
try:
|
try:
|
||||||
suf = m.group('suffix')
|
suf = m.group('suffix')
|
||||||
@ -146,8 +168,8 @@ def siParse(s, regex=FLOAT_REGEX, suffix=None):
|
|||||||
suf = ''
|
suf = ''
|
||||||
else:
|
else:
|
||||||
suf = suffix
|
suf = suffix
|
||||||
|
|
||||||
return m.group('number'), '' if sip is None else sip, '' if suf is None else suf
|
return m.group('number'), '' if sip is None else sip, '' if suf is None else suf
|
||||||
|
|
||||||
|
|
||||||
def siEval(s, typ=float, regex=FLOAT_REGEX, suffix=None):
|
def siEval(s, typ=float, regex=FLOAT_REGEX, suffix=None):
|
||||||
|
@ -423,6 +423,30 @@ def test_eq():
|
|||||||
assert eq(set(range(10)), set(range(10)))
|
assert eq(set(range(10)), set(range(10)))
|
||||||
assert not eq(set(range(10)), set(range(9)))
|
assert not eq(set(range(10)), set(range(9)))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
@pytest.mark.parametrize("s,suffix,expected", [
|
||||||
test_interpolateArray()
|
# usual cases
|
||||||
|
("100 uV", "V", ("100", "u", "V")),
|
||||||
|
("100 µV", "V", ("100", "µ", "V")),
|
||||||
|
("4.2 nV", None, ("4.2", "n", "V")),
|
||||||
|
("1.2 m", "m", ("1.2", "", "m")),
|
||||||
|
("1.2 m", None, ("1.2", "", "m")),
|
||||||
|
("5.0e9", None, ("5.0e9", "", "")),
|
||||||
|
("2 units", "units", ("2", "", "units")),
|
||||||
|
# siPrefix with explicit empty suffix
|
||||||
|
("1.2 m", "", ("1.2", "m", "")),
|
||||||
|
("5.0e-9 M", "", ("5.0e-9", "M", "")),
|
||||||
|
# weirder cases that should return the reasonable thing
|
||||||
|
("4.2 nV", "nV", ("4.2", "", "nV")),
|
||||||
|
("4.2 nV", "", ("4.2", "n", "")),
|
||||||
|
("1.2 j", "", ("1.2", "", "")),
|
||||||
|
("1.2 j", None, ("1.2", "", "j")),
|
||||||
|
# expected error cases
|
||||||
|
("100 uV", "v", ValueError),
|
||||||
|
])
|
||||||
|
def test_siParse(s, suffix, expected):
|
||||||
|
if isinstance(expected, tuple):
|
||||||
|
assert pg.siParse(s, suffix=suffix) == expected
|
||||||
|
else:
|
||||||
|
with pytest.raises(expected):
|
||||||
|
pg.siParse(s, suffix=suffix)
|
||||||
|
@ -466,7 +466,7 @@ class SpinBox(QtGui.QAbstractSpinBox):
|
|||||||
|
|
||||||
# format the string
|
# format the string
|
||||||
val = self.value()
|
val = self.value()
|
||||||
if self.opts['siPrefix'] is True and len(self.opts['suffix']) > 0:
|
if self.opts['siPrefix'] is True:
|
||||||
# SI prefix was requested, so scale the value accordingly
|
# SI prefix was requested, so scale the value accordingly
|
||||||
|
|
||||||
if self.val == 0 and prev is not None:
|
if self.val == 0 and prev is not None:
|
||||||
@ -545,7 +545,7 @@ class SpinBox(QtGui.QAbstractSpinBox):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
# check suffix
|
# check suffix
|
||||||
if suffix != self.opts['suffix'] or (suffix == '' and siprefix != ''):
|
if suffix != self.opts['suffix']:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# generate value
|
# generate value
|
||||||
|
Loading…
Reference in New Issue
Block a user