Is there a way to combine textChanged
and editingFinished
for QLineEdit
? The problem is that editingFinished
is emitted even if I only move the cursor away from QLineEdit
without any changes. Whereas I want to emit a signal only when any changes were performed after I finished editing.
I can imagine only to store somewhere the current text, compare the entered text with it and do something only if it differs. But I wonder if there is any solution purely based on signals handling.
EDIT: At the end I had to store the current text and compare with the new text and not follow the proposed solution. I realized that in my application "1.2345" and "1.23" would be the same text but nevertheless I have to update some other values in this case and so on. I really appreciate detailed answer and comments by @Avaris and @ekhumoro, and will accept it since it seems to solve originally posted problem.
Edit
For capturing manual edits:
class MyLineEdit(QtGui.QLineEdit):
textModified = QtCore.pyqtSignal(str, str) # (before, after)
def __init__(self, contents='', parent=None):
super(MyLineEdit, self).__init__(contents, parent)
self.returnPressed.connect(self.checkText)
self._before = contents
def focusInEvent(self, event):
if event.reason() != QtCore.Qt.PopupFocusReason:
self._before = self.text()
super(MyLineEdit, self).focusInEvent(event)
def focusOutEvent(self, event):
if event.reason() != QtCore.Qt.PopupFocusReason:
self.checkText()
super(MyLineEdit, self).focusOutEvent(event)
def checkText(self):
if self._before != self.text():
self._before = self.text()
self.textModified.emit(self._before, self.text())
Edit 2
For capturing all edits (programmatic and manual):
class MyLineEdit(QtGui.QLineEdit):
textModified = QtCore.pyqtSignal(str, str) # (before, after)
def __init__(self, contents='', parent=None):
super(MyLineEdit, self).__init__(contents, parent)
self.editingFinished.connect(self.checkText)
self.textChanged.connect(lambda: self.checkText())
self.returnPressed.connect(lambda: self.checkText(True))
self._before = contents
def checkText(self, _return=False):
if (not self.hasFocus() or _return) and self._before != self.text():
self._before = self.text()
self.textModified.emit(self._before, self.text())
Edit 3
For capturing only text changes by the user:
class MyLineEdit(QtGui.QLineEdit):
textModified = QtCore.pyqtSignal(str, str) # (before, after)
def __init__(self, contents='', parent=None):
super(MyLineEdit, self).__init__(contents, parent)
self.editingFinished.connect(self.__handleEditingFinished)
self.textChanged.connect(self.__handleTextChanged)
self._before = contents
def __handleTextChanged(self, text):
if not self.hasFocus():
self._before = text
def __handleEditingFinished(self):
before, after = self._before, self.text()
if before != after:
self._before = after
self.textModified.emit(before, after)
If you just want to detect whether any changes have been made (as opposed to whether the text is different from how it started), you can use the modified
property of the QLineEdit
with the editingFinished
signal:
self.edit = QtGui.QLineEdit(self)
self.edit.editingFinished.connect(self.handleEditingFinished)
...
def handleEditingFinished(self):
if self.edit.isModified():
# do interesting stuff ...
print 'Editing Finished'
self.edit.setModified(False)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With