Short version: How can I subclass or otherwise modify a QLineEdit so that the context menu's "undo" option won't undo anything?
Currently I have the following, which blocks Ctrl-Z from working:
class PasswordSaveQLineEdit(QLineEdit):
def keyPressEvent(self,event):
if event.key()==(QtCore.Qt.Key_Control and QtCore.Qt.Key_Z):
self.undo()
else:
QLineEdit.keyPressEvent(self,event)
def undo(self):
pass
I could get away with disabling the context menu, which would then get rid of both possible ways to undo, but I would rather not. The undo()
function doesn't appear to be called directly by either Ctrl-Z or selecting the context menu option.
I also saw this thread on clearing the undo history, which would also work fine, but that unfortunately only applies to Q(Plain)TextEdit and not to QLineEdit.
Explanation of why I need this (in case someone has a better suggestion for how to do it):
Using PyQt4 with the Qt Designer, I'm trying to implement a password entry box (a QLineEdit) where the user can check a box to show or hide the password. This part is working just fine:
def toggleShowPW(self):
doShow = self.form.showPWCheck.isChecked()
if doShow:
self.form.passwordBox.setEchoMode(QLineEdit.Normal)
else:
self.form.passwordBox.setEchoMode(QLineEdit.Password)
self.form.showPWCheck.toggled.connect(self.toggleShowPW)
However, my application also needs an option to save the password and bring it back the next time this dialog is opened. Although the password is being stored in plaintext in the database (and I plan to provide a warning to the user about that when they select the option to save the password), I would like to add at least a little bit of security so that a user who walks by can't look at the password just by ticking the box. So I added an attribute to the class that keeps track of whether the password has been loaded from the configuration file, and changed the method to this:
def toggleShowPW(self):
doShow = self.form.showPWCheck.isChecked()
if doShow:
# if password was saved in the config, don't let it be shown in
# plaintext for some basic security
if self.passwordWasLoaded:
r = utils.questionBox("For security reasons, you cannot view "
"any part of a saved password. Would you like to erase "
"the saved password?", "Erase Password")
if r == QMessageBox.Yes:
self.form.passwordBox.setText("")
self.passwordWasLoaded = False
else:
self.form.showPWCheck.setChecked(False)
return
self.form.passwordBox.setEchoMode(QLineEdit.Normal)
else:
self.form.passwordBox.setEchoMode(QLineEdit.Password)
I also added and connected a method called self.unsetPasswordWasLoaded
, which sets the flag to False if all of the content in the password field is erased.
This works great. Unfortunately, a user can now view the password by erasing all of the content, ticking the box, and then doing an Undo. (It's not possible to do an undo when the echoMode is set to QLineEdit.Password, but when you change it back to normal the undo history persists from before.)