QValidator修复问题

时间:2015-12-02 23:35:34

标签: python pyqt4 qvalidator

以下是验证帐户代码的代码,并按特定间隔添加短划线。示例帐户代码为140-100-1000-6610-543。代码采用正则表达式:\d{3}-\d{3}-\d{4}-\d{4}-\d{3]并允许用户键入数字,并且在正则表达式中有破折号时,它会为用户放置破折号。或者更确切地说,它应该。在我们的生产服务器上((' Qt版本:',' 4.8.1'),(' SIP版本:',' 4.13.2& #39;),(' PyQt版本:',' 4.9.1'))它确实有效。我们的开发服务器已升级到(' Qt版本:',' 4.8.6'),(' SIP版本:',' 4.15。 5'),(' PyQt版本:',' 4.10.4')并且它在那里不起作用。

在每台服务器上,我输入140。在生产(旧版本)上,行编辑值更改为140-。在较新的版本开发服务器上,它不会添加破折号。

如果您发现我的问题,请告诉我,如果这是PyQt问题或Qt问题,请告诉我。

import sys
from PyQt4 import QtGui, QtCore

DEBUG = True

class acValidator(QtGui.QRegExpValidator):

    def __init__(self, regexp, widget):
        QtGui.QRegExpValidator.__init__(self, regexp, widget)
        self.widget = widget

    def validate(self, text, pos):
        '''function to decide if this account code is valid'''
        valid, _npos = QtGui.QRegExpValidator.validate(self, text, pos)

        if valid != QtGui.QValidator.Acceptable:
            self.fixup(text)
            print 'acWidget.validate result of fixup', text

            # move position to the end, if fixup just added a dash
            # to the end
            newstr = self.widget.text()
            newpos = len(str(newstr))
            if pos + 1 == newpos and newstr[pos:newpos] == '-':
                pos = newpos

        # return the valid variable, and the current position
        return (valid, pos)

    def fixup(self, text):
        '''place dashes, if we can'''
        # pylint: disable=no-member
        if DEBUG:
            print 'acWidget.py fixup'
        reParts = self.regExp().pattern().split('-')
        if DEBUG:
            print list(reParts)
        newreg = ''
        for i in range(len(reParts)):
            newreg += reParts[i]
            if DEBUG:
                print i, reParts[i]

            nr = QtCore.QRegExp(newreg)
            # pylint: disable=no-member
            if nr.exactMatch(text) and not self.regExp().exactMatch(text):
                if DEBUG:
                    print 'adding dash'
                text += '-'
                return

            newreg += '-'

    def isValid(self):
        '''return a true or false for the validity based on whether the
        widget is a lineEdit or a comboBox (acCB).  true only if the
        validator returns QtGui.QValidator.Acceptable
        '''
        valid, _npos = QtGui.QRegExpValidator.validate(self,
                        self.widget.text(),
                        self.widget.cursorPosition())
        if valid == QtGui.QValidator.Acceptable:
            return True

        return False


class acWidget(QtGui.QLineEdit):

    def __init__(self, parent=None):
        QtGui.QLineEdit.__init__(self, parent)

        self.regex = r'\d{3}-\d{3}-\d{4}-\d{4}-\d{3}'
        self.setMinimumWidth(200)
        self.setValidator(acValidator(QtCore.QRegExp(self.regex),
                    self))

if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)
    form = QtGui.QDialog()
    layout = QtGui.QVBoxLayout(form)
    a = acWidget(form)
    layout.addWidget(a)
    form.setLayout(layout)
    form.setMinimumWidth(400)
    form.setMinimumHeight(200)
    form.show()
    app.exec_()

1 个答案:

答案 0 :(得分:1)

问题是由fixupvalidate的C ++签名引起的,要求 text 参数可修改。如果您使用的是Python 2,PyQt会对这种明显无意义的做事方式表示敬意;而对于Python 3,signatures have been changed使方法只返回修改后的值。

您可以在此处找到代码中的具体问题:

    def fixup(self, text):
        ...

        text += '-'

似乎在早期版本的PyQt中,QString上的扩充赋值做了一个隐含的就地变异。但是在更新的版本中,它更像普通的python扩充赋值,只需重新绑定局部变量,如下所示:

        text = text + '-'

要解决此问题,您可以进行明确的就地变异:

        text.append('-')