2

我创建了一个 QLineEdit 并为其附加了一个自定义 QValidator。我试图向fixup()我的 QValidator 添加一个函数。当我在 QLineEdit 中输入一些文本时,它会调用validate(),然后调用fixup(),最后validate()再次调用,但仍然像修复之前的文本一样。我做错了什么?为什么 QLineEdit 没有被修复更新?

mylineedit = QtGui.QLineEdit()
mylineedit.setValidator(MyValidator())

class MyValidator(QtGui.QRegExpValidator):
    def __init__(self, parent=None):
        rx = QtCore.QRegExp('\\d+ m')
        super().__init__(rx, parent)

    def validate(self, text, pos):
        r = super().validate(text, pos)
        print(r)
        return r

    def fixup(self, text):
        if len(text) == 0:
            text = '0 m'
        else:
            text = text.strip() + ' m'
        print(text)
        return text

输出将类似于(如果我按“1”+ Enter):

(PySide.QtGui.QValidator.State.Intermediate, '1', 1)
1 m
(PySide.QtGui.QValidator.State.Intermediate, '1', 1)
4

2 回答 2

1

我认为PySide中QValidator的默认实现并不好,原因如下:

  1. validate()每当输入或删除字符时,甚至在输入完成之前,都会调用该方法。这可能会使编辑字段变得不可能,因为对目标字符串的所有编辑都是无效的并被拒绝。
  2. fixup()方法被破坏,它的返回值被丢弃。

但是有一个解决方法。将QLineEdit自身传递给验证器构造函数,然后您可以控制它何时被验证并根据需要修复它的值:

class MyValidator(QValidator):

  def __init__(self, lineedit):
    super(MyValidator, self).__init__()
    self.lineedit = lineedit

  def validate(self, s, p):
    if self.lineedit.hasFocus(): #ignore validation while editing not complete
      return QValidator.Acceptable
    if s.startswith("http://"):
      return QValidator.Acceptable
    return QValidator.Invalid

  def fixup(self, s):
    self.lineedit.setText("http://" + s)
于 2014-04-19T22:21:42.533 回答
1

根据 MadeOfAirs 的回答,提出了以下替换空白的方法。不过,它会为每个小部件创建一个新的验证器。

class QLineEditValidator(QValidator):

    @classmethod
    def connect(cls, line_edit, fixup=lambda s: s, validate=None, **kwargs):
        line_edit.setValidator(cls(line_edit, fixup=fixup, validate=validate, **kwargs))

    def __init__(self, line_edit, fixup=lambda s: s, validate=None, **kwargs):
        super().__init__(**kwargs)
        self.line_edit, self._fixup, self._validate = line_edit, fixup, \
            (lambda s, p: fixup(s) == s) if validate is None else validate

    def validate(self, s, p):
        if self.line_edit.hasFocus():
            return QValidator.Acceptable
        return QValidator.Acceptable if self._validate(s, p) else QValidator.Invalid

    def fixup(self, s):
        self.line_edit.setText(self._fixup(s))

text = QLineEdit()
QLineEditValidator.connect(text, fixup=lambda s: s.replace(' ', '_'))
QLineEditValidator.connect(text, fixup=lambda s: s.replace(' ', '_'), 
    validate=lambda s, p: not ' ' in s)
于 2015-08-12T10:23:04.510 回答