Source code for silx.gui.widgets.FloatEdit
# /*##########################################################################
#
# Copyright (c) 2004-2023 European Synchrotron Radiation Facility
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# ###########################################################################*/
"""Module contains a float editor"""
from __future__ import annotations
__authors__ = ["V.A. Sole", "T. Vincent"]
__license__ = "MIT"
__date__ = "02/10/2017"
from .. import qt
[docs]
class FloatEdit(qt.QLineEdit):
"""Field to edit a float value.
The value can be modified with :meth:`value` and :meth:`setValue`.
The property :meth:`widgetResizable` allow to change the default
behaviour in order to automatically resize the widget to the displayed value.
Use :meth:`setMinimumWidth` to enforce the minimum width.
:param parent: Parent of the widget
:param value: The value to set the QLineEdit to.
"""
_QLineEditPrivateHorizontalMargin = 2
"""Constant from Qt source code"""
def __init__(self, parent: qt.QWidget | None = None, value: float | None = None):
qt.QLineEdit.__init__(self, parent)
validator = qt.QDoubleValidator(self)
self.__widgetResizable: bool = False
self.__minimumWidth = 30
"""Store the minimum width requested by the user, the real one is
dynamic"""
self.setValidator(validator)
self.setAlignment(qt.Qt.AlignRight)
self.textChanged.connect(self.__textChanged)
if value is not None:
self.setValue(value)
[docs]
def value(self) -> float:
"""Return the QLineEdit current value as a float."""
text = self.text()
value, validated = self.validator().locale().toDouble(text)
if not validated:
self.setValue(value)
return value
[docs]
def setValue(self, value: float):
"""Set the current value of the LineEdit
:param value: The value to set the QLineEdit to.
"""
locale = self.validator().locale()
if qt.BINDING == "PySide6":
# Fix for PySide6 not selecting the right method
text = locale.toString(float(value), "g")
else:
text = locale.toString(float(value))
self.setText(text)
if self.__widgetResizable:
self.__forceMinimumWidthFromContent()
def __textChanged(self, text: str):
if self.__widgetResizable:
self.__forceMinimumWidthFromContent()
def __minimumWidthFromContent(self) -> int:
"""Minimum size for the widget to properly read the actual number"""
text = self.text()
font = self.font()
metrics = qt.QFontMetrics(font)
margins = self.textMargins()
width = (
metrics.horizontalAdvance(text)
+ self._QLineEditPrivateHorizontalMargin * 2
+ margins.left()
+ margins.right()
)
width = max(self.__minimumWidth, width)
opt = qt.QStyleOptionFrame()
self.initStyleOption(opt)
s = self.style().sizeFromContents(
qt.QStyle.CT_LineEdit, opt, qt.QSize(width, self.height())
)
return s.width()
def sizeHint(self) -> qt.QSize:
sizeHint = qt.QLineEdit.sizeHint(self)
if not self.__widgetResizable:
return sizeHint
width = self.__minimumWidthFromContent()
return qt.QSize(width, sizeHint.height())
def __forceMinimumWidthFromContent(self):
width = self.__minimumWidthFromContent()
qt.QLineEdit.setMinimumWidth(self, width)
self.updateGeometry()
def setMinimumWidth(self, width: int):
self.__minimumWidth = width
qt.QLineEdit.setMinimumWidth(self, width)
self.updateGeometry()
[docs]
def minimumWidth(self) -> int:
"""Returns the user defined minimum width."""
return self.__minimumWidth