0

I am looking for a way to force the groupSeparator symbol of a doublespinbox.

For context, one of my programs uses an numerical input (doublespinbox) + unit choices (radio buttons) to form a number. It looks roughly like this:

voltage [ 5 ] o V
              o mV
              o µV

I use a group separator to make reading easier. On a French machine I get a satisfying display, where for example 1 thousand and 1 look like so: 1 000 or 1,000. On an English machine, I get 1,000 and 1.000 which can be easily confused. How could I force the group separator to be always a space?

Alternatively, I believe that a solution could be to force the locale of the program as answered here but I'm always interested in seeing if custom solutions are possible. Otherwise, I'll stick to

self.setLocale(QtCore.QLocale(QtCore.QLocale.French))
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Guimoute
  • 4,407
  • 3
  • 12
  • 28

1 Answers1

2

Another possibility is to reimplement your own subclass for the spinbox and override the textFromValue() function:

class SpaceSeparatorSpin(QtWidgets.QDoubleSpinBox):
    def textFromValue(self, value):
        text = self.locale().toString(float(value), 'f', self.decimals())
        return text.replace(self.locale().groupSeparator(), ' ')

In this way, we use the current (default) locale to transform the value to a string and then return the string with the separator replaced with the space.

There are some issues with both approaches, though.

Using a custom locale for a single widget class can result in unexpected behavior when using copy&paste functions: if the user lives in a country that uses the point for the decimals, a simple "50.2" value that might be taken from another source will not be pasted, as the validator will not recognize that string as valid (for the French locale, it should be "50,2").

Using the textFromValue override has the opposite problem if the user wants to copy from a subclassed spinbox to another, as the space separator will make the validator ignore the string when the spinbox calls valueFromText().

To avoid all that, you could override the validate() function: if the base implementation returns a valid or intermediate value, return it, otherwise validate it on your own being careful about the current locale and the possibility of the "double input possibilities" (with or without spaces, inverted points/commas for decimals and group separators); note that while pasting a "space-separated" value on a locale that uses them works, QAbstractSpinBox doesn't accept spaces when typing.

Besides all that, keep in mind that using "de-localized" decimal points and separator is not a good thing. While it might seem fine for you, user with other types of punctuations will probably find it very annoying, especially for people that are used to the numeric pad: usually, the decimal point key of the pad is configured with that of the system locale, so users that have a locale that uses the point for decimals won't be able to type decimals from the pad, forcing them to move their hand away from it to type the comma.

musicamante
  • 41,230
  • 6
  • 33
  • 58
  • Thank you for all the information. That sounds like a lot of work and overriding only to replace one character. I hear your point about annoying the users by forcing on them the point or comma convention regardless of keyboard type. I guess the ideal case would be to actually take the time to dive into that and make a custom class with everything you talked about + multi-locales supported + other details that I'd like (like how "0.000" from a doublespinbox should == int(0) and it does not because of float imprecisions), etc. – Guimoute Dec 05 '19 at 13:26
  • Well, there's also the possibility of overriding the paintEvent of the spinbox lineEdit (adding a "space margin" whenever required or changing the displayed text that is going to be painted), but that would be a massive overshooting: custom painting of a QLineEdit is very difficult to achieve and prone to bugs if not done with extreme care, also because you'll have to take into account different font sizes for separators and mouse interaction/keyboard navigation. – musicamante Dec 05 '19 at 13:41
  • Ahah perfect, it's even more prone to bugs considering that I automatically resize all my widgets and their fontsize depending on the screen resolution! I'll pass then :) – Guimoute Dec 05 '19 at 14:01