2

I'm attempting to write a custom QDoubleSpinBox subclass which has a scaling factor / function between it's internal value and the displayed value. The purpose of this is to support displaying the same internal value in different units (e.g. allow the user to select whether to display metres, millimetres or inches, but always store the actual value in metres).

Overriding QDoubleSpinBox::textFromValue was quite simple to scale the internal value and append a unit symbol. However the valueFromText() and validate() methods have a lot of internal logic which enforces the min / max bounds. Since these are in a different unit system to what the user is working in, it limits the user to incorrect min and max values.

Ideally I would like to avoid reimplementing / copy and pasting all of this internal private logic just to implement scaling of the value when parsing it from text. Does anyone have any suggestions on how to avoid this?

ajshort
  • 3,684
  • 5
  • 29
  • 43
  • This logic doesn't belong to a widget. I would recommend to do the unit conversion before you set the value into the widget. That would be most likely inside the model that provides data for this widget. – Jaa-c Jul 22 '18 at 17:11
  • @Jaa-c I'm curious about this reasoning - the unit conversion is purely presentational and the model always uses the same internal units for its actual data, so I would have thought a widget would be the perfect place for this display-only logic? – ajshort Jul 23 '18 at 01:56
  • 1
    I have an experience with quite large Qt application where we had to handle units a lot. Maybe if you have very simple requirements for units, it will be easier to implement in the widget. But if you start saving current unit settings to some config, create some bigger abstraction for the units (different units for different widgets), start handling more complicated units with shifts (like temperatures) etc, it will be a real pain to do all this stuff in a widget. – Jaa-c Jul 23 '18 at 07:05

1 Answers1

0

I'd suggest you take a look into QDataWidgetMapper. It contains a model, which can be different from the display value. It's typically used when you have more than one widget, but can be used for one single widget too.

Qt has an example that shows how to use it: http://doc.qt.io/qt-5/qtwidgets-itemviews-simplewidgetmapper-example.html

You will have to create a QStandardItemModel and specify how many rows/column you want it to hold. In the case of QDoubleSpinBox it can be just one column. Then you can listen to the changes in the model and update your view (which is QDoubleSpinBox) accordingly.

It's highly customizable and easy to use.

santahopar
  • 2,933
  • 2
  • 29
  • 50