我正在使用QLineEdit小部件输入电子邮件地址,并设置了一个QRegExpValidor来验证输入
验证器正在尽可能地防止输入QRegExp中不允许的字符,但有趣的是,它允许通过按下enter键或触发“editingfinished”信号来输入中间输入
我验证了验证器的返回是否正确(中间或可接受)
检查PyQt5文档,确认验证器的中间状态不会阻止焦点更改为另一个小部件。此外,它会停止触发editingFinished和returnedPressed信号,因此用户可能会输入错误的地址,直到部分进入RegExp。 参考:https://doc.qt.io/qt-5/qlineedit.html#acceptableInput-prop
我可以通过从QLineEdit小部件中删除验证器,并放置一个方法“checkValidator”,链接到QLineEdit小部件的cursorPositionChanged,将不可访问时输入的最后一个字符分割,并在验证Intermediate时将焦点设置回QLineEdit来解决我的需要。它工作得很好,但是当焦点被重置时,其他小部件上的其他信号一次触发一个。暂时,我通过检查发送者在方法的开头是否有焦点来处理这个问题(参见lookForFile)
尽管我可以处理这个问题,但我非常感谢任何人向我解释使用RegExpValidator的正确方法,以及为什么重置焦点会突然触发其他信号
def setUI(self):
self.setWindowTitle("EMail Settings")
self.setModal(True)
rx = QRegExp(r"[a-z0-9_%]+@[a-z0-9%_]+\.[a-z0-9%_]{3,3}")
lblAddress = QLabel("EMail Address")
self.lineAddress = QLineEdit(self)
self.mailValidator = QRegExpValidator(rx, self.lineAddress)
#self.lineAddress.setValidator(self.mailValidator)
self.lineAddress.cursorPositionChanged.connect(self.checkValidator)
self.lineAddress.returnPressed.connect(self.checkValidator)
lblPassword = QLabel("Password")
self.linePwd = QLineEdit()
self.linePwd.setEchoMode(QLineEdit.PasswordEchoOnEdit)
lblOauth2 = QLabel("Oauth2 Token")
self.lineOauth = QLineEdit()
pushOauth = QPushButton("...")
pushOauth.setObjectName("token")
pushOauth.clicked.connect(self.lookForFile)
pushOauth.setFixedWidth(30)
@pyqtSlot()
def checkValidator(self):
self.lineAddress.blockSignals(True)
v = self.mailValidator.validate(self.lineAddress.text(), len(self.lineAddress.text()))
if v[0] == 0:
self.lineAddress.setText(self.lineAddress.text()[:-1])
elif v[0] == 1:
self.lineAddress.setFocus()
elif v[0] == 2:
pass
print("validates", v)
self.lineAddress.blockSignals(False)
@pyqtSlot()
def lookForFile(self):
try:
if not self.sender().hasFocus():
return
baseDir = "C"
obj = self.sender()
if obj.objectName() == "Draft":
capt = "Email Draft"
baseDir = os.getcwd() + "\\draft"
fileType = "Polo Management Email (*.pad)"
dialog = QFileDialog(self, directory=os.getcwd())
dialog.setFileMode(QFileDialog.Directory)
res = dialog.getExistingDirectory()
elif obj.objectName() == "token":
capt = "Gmail Outh2 token File"
fileType = "Gmail token Files (*.json)"
baseDir = self.lineOauth.text()
res = QFileDialog.getOpenFileName(self, caption=capt, directory=baseDir, filter=fileType)[0]
fileName = res
if obj.objectName() == "Draft":
self.lineDraft.setText(fileName)
elif obj.objectName() == "tokenFile":
self.lineOauth.setText(fileName)
except Exception as err:
print("settings: lookForFile", err.args)
希望用这个最小的可复制示例回答@eyllanesc和Qmusicmante的请求。我将正则表达式更改为一个简单的正则表达式,允许一个小写a-z字符串后跟一个点和三个以上的小写字符
我的意图是验证程序不允许用户输入错误的输入。该示例允许使用“xxxzb.ods”,但也允许使用例如“xxxzb”或“xxxzb.o”。 简而言之,不允许用户输入错误的输入
这是我的最小可复制示例:
class CheckValidator(QDialog):
def __init__(self, parent=None):
super().__init__()
self.parent = parent
self.setUI()
def setUI(self):
self.setWindowTitle("EMail Settings")
self.setModal(True)
rx = QRegExp(r"[a-z]+\.[a-z]{3}")
lblAddress = QLabel("Check Line")
self.lineAddress = QLineEdit()
self.mailValidator = QRegExpValidator(rx, self.lineAddress)
self.lineAddress.setValidator(self.mailValidator)
self.lineAddress.cursorPositionChanged[int, int].connect(lambda
oldPos, newPos: self.printValidator(newPos))
lblCheck = QLabel("Check")
lineCheck = QLineEdit()
formLayout = QFormLayout()
formLayout.addRow(lblAddress, self.lineAddress)
formLayout.addRow(lblCheck, lineCheck)
self.setLayout(formLayout)
@pyqtSlot(int)
def printValidator(self, pos):
print(self.mailValidator.validate(self.lineAddress.text(), pos))
if __name__ == '__main__':
app = QApplication(sys.argv)
tst = CheckValidator()
tst.show()
app.exec()
我找到了一个解决方案,我把它贴在这里,这样的情况可能会帮助别人。 首先,我从QLineEdit小部件中删除QRegExpValidator。原因是QLineEdit仅在QRegExpValidator返回QValidator.Acceptable时才会激发editingFinished(我们需要它),而验证程序存在
然后,我们设置一个由QlineEdit小部件的“cursorPositionchanged”信号触发的方法。在这个方法中,我们使用QRegExpValidator确定最后输入的字符是否有效。如果不是,我们就把它移除
最后,我使用RegEx exactMatch函数设置了由“editingFinished”信号触发的方法,以确定条目是否有效。如果不是,我们给用户清除条目或返回小部件继续输入数据的选项。使用的正则表达式仅用于测试目的,有关电子邮件验证检查@Musicamante注释的更多信息
这就是所涉及的代码:
相关问题 更多 >
编程相关推荐