首页 > 解决方案 > 空时如何让 QIntValidator() 调用editingFinished?

问题描述

我有一个带有 QIntValidator 的 Line Edit 小部件:

number_textbox = QLineEdit()
number_textbox.setText("0")
number_textbox.setValidator(QIntValidator())

此外,我将文本框的旧值存储在字典中:

old_val[uid_key] = 0

我希望能够,当文本框为空时,如果用户在框外单击或按回车键,则将文本框中的文本替换为旧值:

number_textbox.editingFinished.connect(lambda: self.editing_finished_function(number_textbox, old_val[uid_key]))

def editing_finished_function(self, textbox, old_val):
    if textbox.text() == '':
        textbox.setText(old_val)
    else:
        old_val = textbox.text()

不幸的是, QIntValidator() 似乎将空值视为无效,并且从不触发我的函数。有没有办法做我在这里寻找的东西?

标签: pythonpyqt5qvalidator

解决方案


来自文档:

无效 QLineEdit::editingFinished()

当按下 Return 或 Enter 键或行编辑失去焦点时,会发出此信号。请注意,如果在行编辑上设置了 validator() 或 inputMask() 并按下了 enter/return,则仅当输入跟随 inputMask() 并且 validator() 返回 QValidator 时才会发出 editingFinished() 信号: : 可以接受。

并且 QIntValidator 似乎并不认为空字符串是有效的。所以我建议你使用创建自己的验证器QRegExpValidator

下面是接受数字和空字符串的验证器

regexp = QtCore.QRegExp('(^[0-9]+$|^$)')
validator = QtGui.QRegExpValidator(regexp)

完整示例:

import sys
from PyQt5 import QtWidgets, QtGui, QtCore


class MainWidget(QtWidgets.QWidget):

    old_val = {'val': '0'}

    def __init__(self):
        super(MainWidget, self).__init__()

        self.setLayout(QtWidgets.QVBoxLayout())
        self.setFocusPolicy(QtCore.Qt.ClickFocus)

        regexp = QtCore.QRegExp('(^[0-9]+$|^$)')
        validator = QtGui.QRegExpValidator(regexp)

        number_textbox = QtWidgets.QLineEdit()
        number_textbox.setText(self.old_val['val'])
        number_textbox.setValidator(validator)
        number_textbox.editingFinished.connect(lambda: self.editing_finished_function(number_textbox))

        self.layout().addWidget(number_textbox)

    def editing_finished_function(self, textbox):
        print("FINISHED")
        if textbox.text() == '':
            textbox.setText(self.old_val['val'])

        else:
            self.old_val['val'] = textbox.text()


if __name__ == '__main__':

    app = QtWidgets.QApplication(sys.argv)

    widget = MainWidget()
    widget.show()

    sys.exit(app.exec_())

推荐阅读