【问题标题】:PyQt4: combine textChanged and editingFinished for QLineEditPyQt4:结合 textChanged 和 editingFinished 为 QLineEdit
【发布时间】:2012-08-24 07:28:06
【问题描述】:

有没有办法将textChangededitingFinished 组合成QLineEdit?问题是即使我只将光标从QLineEdit 移开而没有任何更改,也会发出editingFinished。而我只想在完成编辑后执行任何更改时才发出信号。

我可以想象只将当前文本存储在某个地方,将输入的文本与它进行比较,并且只有当它不同时才做某事。但是我想知道是否有任何纯粹基于信号处理的解决方案。

编辑:最后我不得不存储当前文本并与新文本进行比较,而不是遵循建议的解决方案。我意识到在我的应用程序中“1.2345”和“1.23”将是相同的文本,但在这种情况下我必须更新一些其他值等等。我非常感谢@Avaris 和@ekhumoro 的详细答案和cmets,并且会接受它,因为它似乎解决了最初发布的问题。

【问题讨论】:

    标签: qt qt4 pyqt pyqt4


    【解决方案1】:

    编辑

    用于捕获手动编辑:

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

    编辑 2

    用于捕获所有编辑(编程和手动):

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

    编辑 3

    仅捕获用户的文本更改:

    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)
    

    【讨论】:

    • 您的解决方案似乎不完整。例如,如果打开了行编辑的上下文菜单,信号就会触发(所以也许你需要检查event.reason())。此外,如果按下返回/回车,信号 不会 触发 - 因此需要一些键盘处理。
    • @ekhumoro:你在这些问题上是对的。更新了我的答案。
    • 不错 - 但如果setText()clear() 在编辑之间被调用?
    • @ekhumoro:啊,这将变成一个新的QLineEdit 实现:)。然后是delbackspaceinsert 等......嗯,我想我有一个适合所有人的解决方案。
    • 我认为应该在发出任何信号之前设置_before 属性,因为文本可以由处理程序修改。但即便如此:OP 的规格是否匹配? “只有在我完成编辑后执行任何更改时”才应该发出信号。而您当前的解决方案也可能在程序文本更改后发出textModified
    【解决方案2】:

    如果您只想检测是否进行了任何更改(而不是文本是否与开始的方式不同),您可以使用QLineEditmodified 属性使用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)
    

    【讨论】:

    • 请注意,modified 将保持切换状态,即使您在完成编辑之前将其恢复为原始值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-03
    • 2015-11-18
    • 1970-01-01
    • 2016-03-27
    • 2017-11-21
    相关资源
    最近更新 更多