2012-08-29 30 views
10

¿Hay alguna manera de combinar textChanged y editingFinished para QLineEdit? El problema es que editingFinished se emite incluso si solo muevo el cursor fuera de QLineEdit sin ningún cambio. Mientras que quiero emitir una señal solo cuando se realizaron cambios después de que terminé de editar.PyQt4: combine textChanged y editingFinished para QLineEdit

Puedo imaginar almacenar solo en algún lugar el texto actual, comparar el texto introducido con él y hacer algo solo si es diferente. Pero me pregunto si hay alguna solución puramente basada en el manejo de señales.

EDIT: Al final tuve que almacenar el texto actual y compararlo con el nuevo texto y no seguir la solución propuesta. Me di cuenta de que en mi aplicación "1.2345" y "1.23" sería el mismo texto, pero de todos modos tengo que actualizar algunos otros valores en este caso, y así sucesivamente. Realmente aprecio la respuesta detallada y los comentarios de @Avaris y @ekhumoro, y los aceptaré, ya que parece que resuelve el problema originalmente publicado.

Respuesta

9

Editar

para la captura de ediciones manuales:

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()) 

Editar 2

Para capturar todas las ediciones (programático y 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()) 

Datos 3

Para capturar sólo los cambios en el texto por el usuario:

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) 
+0

Su solución parece incompleta. Por ejemplo, la señal se disparará si se abre el menú contextual de la edición de línea (por lo que tal vez necesite comprobar 'event.reason()'). Además, la señal * no * disparará si se presiona return/enter, por lo que es necesario algún manejo del teclado. – ekhumoro

+1

@ekhumoro: tienes razón sobre esos problemas. Actualizado mi respuesta. – Avaris

+0

No está mal, pero ¿qué pasa si p. 'setText()' o 'clear()' se llama entre ediciones? – ekhumoro

5

Si lo que desea es detectar si se han realizado cambios (en contraposición a si el texto es diferente de la forma en que iniciado), se puede utilizar la propiedad modified del QLineEdit con la señal editingFinished:

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)