简短版本:我如何子类化或以其他方式修改QLineEdit,以便上下文菜单的“撤消”选项不会撤消任何内容?
目前我有以下内容阻止Ctrl-Z工作:
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
我可以放弃禁用上下文菜单,这样可以摆脱两种可能的撤消方式,但我宁愿不这样做。 {-1}}函数似乎不是由Ctrl-Z直接调用或选择上下文菜单选项。
我还在清除撤消历史记录中看到this thread,这也可以正常工作,但不幸的是,它只适用于Q(普通)TextEdit而不适用于QLineEdit。
解释为什么我需要这个(如果有人对如何做更好的建议):
将PyQt4与Qt Designer一起使用,我正在尝试实现一个密码输入框(QLineEdit),用户可以在其中选中一个框以显示或隐藏密码。这部分工作正常:
undo()
但是,我的应用程序还需要一个保存密码的选项,并在下次打开此对话框时将其恢复。虽然密码以明文形式存储在数据库中(我计划在用户选择保存密码的选项时向用户提供警告),但我想添加至少一点安全性,以便走过的用户只需勾选方框就无法查看密码。所以我在类中添加了一个属性,用于跟踪是否已从配置文件加载密码,并将方法更改为:
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)
我还添加并连接了一个名为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)
的方法,如果密码字段中的所有内容都被删除,它会将标志设置为False。
这很有效。不幸的是,用户现在可以通过删除所有内容,勾选框,然后执行撤消来查看密码。 (当echoMode设置为QLineEdit.Password时,无法执行撤消操作,但当您将其更改回正常时,撤消历史记录将保持不变。)
答案 0 :(得分:1)
您需要覆盖上下文菜单的创建方式,以便禁用“撤消”选项。如果将状态存储在其他位置,则可以根据该状态选择是启用还是禁用撤消选项。一个非常基本的例子 -
# context menu requested signal handler
def display_context_menu(point):
global line_edit
# grab the standard context menu
menu = line_edit.createStandardContextMenu()
# search through the actions i nthe menu to find undo
for action in menu.actions():
if action.text() == '&Undo Ctrl+Z':
# set undo as disabled
action.setDisabled(True)
break
# show context menu where we right clicked
menu.exec_(line_edit.mapToGlobal(point))
# create line edit, set it to use a custom context menu, connect the context menu signal to handler
line_edit = QLineEdit()
line_edit.setContextMenuPolicy(Qt.CustomContextMenu)
line_edit.customContextMenuRequested.connect(display_context_menu)
line_edit.show()