I'm using QLineEdit widgets in my application to enter and edit numeric (float) values. I would like to display a rounded version of the float value while keeping the full internal accuracy. Only when editing a QLineEdit field, the full number of digits should be displayed.
This is needed for three reasons:
complex values need way too much space for my GUI
The UI allows to select between log and linear representation and I'd like to hide the resulting numeric inaccuracies.
Simply rounding the value contained and displayed in QLineEdit is not an option as I would lose accuracy when editing the displayed value
Does anybody know a neat solution for this problem?
Below you find a MWE, the full code (pyfda) uses dynamic instantiation of widgets and other ugly stuff.
# -*- coding: utf-8 -*-
from __future__ import print_function, division
import numpy as np
import sys
from PyQt4 import QtGui
class InputNumFields(QtGui.QWidget):
def __init__(self, parent):
super(InputNumFields, self).__init__(parent)
self.edit_input_float = 10*np.log10(np.pi) # store in log format
self._init_UI()
def _init_UI(self):
self.edit_input = QtGui.QLineEdit()
self.edit_input.editingFinished.connect(self.store_entries)
self.lay_g_main = QtGui.QGridLayout()
self.lay_g_main.addWidget(self.edit_input, 0, 0)
self.setLayout(self.lay_g_main)
self.get_entries()
def store_entries(self):
""" Store text entry as log float"""
self.edit_input_float = 10*np.log10(float(self.edit_input.text()))
self.get_entries()
def get_entries(self):
""" Retrieve float value, delog and convert to string """
self.edit_input.setText(str(10**(self.edit_input_float/10)))
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
mainw = InputNumFields(None)
app.setActiveWindow(mainw)
mainw.show()
sys.exit(app.exec_())
It seems that the behaviour should be this:
This implies that rounding must not occur when return or enter is pressed (because the line-edit would not lose focus in that case).
The above behaviour can be achieved with the following changes:
from PyQt4 import QtCore, QtGui
class InputNumFields(QtGui.QWidget):
...
def _init_UI(self):
self.edit_input = QtGui.QLineEdit()
self.edit_input.installEventFilter(self)
...
def eventFilter(self, source, event):
if (event.type() == QtCore.QEvent.FocusIn and
source is self.edit_input):
self.get_entries()
return super(InputNumFields, self).eventFilter(source, event)
def get_entries(self):
value = 10**(self.edit_input_float/10)
if not self.edit_input.hasFocus():
value = round(value, 3)
self.edit_input.setText(str(value))
PS:
You should probably add a button or something to your example, so you can test the effects of changing focus.