防止在特定文本框中撤消

时间:2015-08-10 22:07:32

标签: python-2.7 pyqt4

简短版本:我如何子类化或以其他方式修改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时,无法执行撤消操作,但当您将其更改回正常时,撤消历史记录将保持不变。)

1 个答案:

答案 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()