Skip to content

Commit

Permalink
fix: make InfDoubleSpinBox more user-friendly
Browse files Browse the repository at this point in the history
  • Loading branch information
paulmueller committed Jun 19, 2021
1 parent cd9593d commit dda5dc3
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 10 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
0.9.1
- fix: regression where left fitting range could not be set
- fix: improved checks for InfDoubleSpinBox which acted up when
entering absolutely sane floating point values
0.9.0
- feat: allow users to enter missing metadata during loading
of data files (#5)
Expand Down
2 changes: 1 addition & 1 deletion pyjibe/fd/tab_edelta.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def on_delta_guess(self):
value /= units.scales["µ"]
self.delta_spin.setValue(value)

@QtCore.pyqtSlot()
@QtCore.pyqtSlot(float)
def on_delta_change_spin(self, value):
"""Indentation depth spin control value changed"""
# Update all controls
Expand Down
48 changes: 40 additions & 8 deletions pyjibe/head/infdoublespinbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,54 @@ def valueFromText(self, text):
return convert_string_to_float(text)

def textFromValue(self, value):
return str(value)
text = f"{value:.7g}"
if not text.count("e"):
# We don't have the exponential notation.
text = str(value)
return text


class FloatValidator(QtGui.QValidator):
def __init__(self, *args, **kwargs):
super(FloatValidator, self).__init__(*args, **kwargs)
self.previous = None

def validate(self, string, position):
if valid_float_string(string):
previous = self.previous
self.previous = string

if string.count(".") > 1:
# if user types "." and there is already a dot, let the cursor
# move to the other side
if not string[position-1] == ".":
# user pressed "." another time -> don't go forward
position -= 1
a, b = string.split(".", 1)
string = ".".join([a, b.replace(".", "")])

return self.Acceptable, string, position
if string == "" or string[position-1] in 'e.-+':
elif (previous is not None and previous.count(".")
and not string.count(".") and position == previous.index(".")):
# make sure removing decimal point does not lead to large numbers
# (1.003 -> 1003)
string = string[:position]
return self.Acceptable, string, position
elif string == "":
return self.Intermediate, string, position
return self.Invalid, string, position
elif string and string[position-1] in '.e-+':
# remove trailing numbers
return self.Intermediate, string.rstrip("0"), position
elif valid_float_string(string):
return self.Acceptable, string, position
else:
return self.Invalid, string, position

def fixup(self, text):
try:
val = convert_string_to_float(text)
text = convert_string_to_float(text)
except ValueError:
val = ""
return str(val)
text = ""
return text


def valid_float_string(string):
Expand All @@ -52,6 +83,7 @@ def valid_float_string(string):


def convert_string_to_float(string):
"""Convert string of float or +/- "inf" to float"""
try:
val = float(string)
except ValueError:
Expand All @@ -63,7 +95,7 @@ def convert_string_to_float(string):
string = string.strip("+-")
for iid in ["i", "in", "inf"]:
if string == iid:
val = asign*np.inf
val = asign * np.inf
break
else:
raise ValueError("Not a valid float!")
Expand Down
30 changes: 29 additions & 1 deletion tests/test_fd_fit.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
data_path = pathlib.Path(__file__).parent / "data"


class MockModel():
class MockModel:
def __init__(self, model_key, **kwargs):
# rebase on hertz model
md = nmodel.models_available["hertz_para"]
Expand Down Expand Up @@ -248,3 +248,31 @@ def test_remember_initial_params(qtbot):
cl2 = war.list_curves.itemBelow(cl1)
war.list_curves.setCurrentItem(cl2)
assert float(itab.item(1, 1).text()) == 5


def test_set_indentation_depth_manually_infdoublespinbox(qtbot):
main_window = pyjibe.head.PyJibe()
main_window.load_data(files=make_directory_with_data(2))
war = main_window.subwindows[0].widget()
# perform fitting with standard parameters
# set initial parameters in user interface
itab = war.tab_fit.table_parameters_initial
# set value for contact point
itab.item(3, 1).setText(str(12345))
# change the model to pyramidal
pyr_name = nmodel.model_hertz_three_sided_pyramid.model_name
pyr_idx = war.tab_fit.cb_model.findText(pyr_name)
war.tab_fit.cb_model.setCurrentIndex(pyr_idx)
# set left fitting range
for text_entered, resulting_value in [
["-1.40", -1.4],
["1...2", 1.2],
["1.0e-4", 1e-4],
["inf", np.inf],
["1.10201", 1.10201],
["1.001", 1.001],
["-1.04", -1.04]
]:
war.tab_fit.sp_range_1.clear()
qtbot.keyClicks(war.tab_fit.sp_range_1, text_entered)
assert war.tab_fit.sp_range_1.value() == resulting_value

0 comments on commit dda5dc3

Please sign in to comment.