zoukankan      html  css  js  c++  java
  • Qt之密码框不可选中、复制、粘贴、无右键菜单等

    简述

    在做用户登录、修改密码的时候,往往会用到密码框,其中一些功能要求与普通的输入框不同,例如:不能选中、复制、粘贴、无右键菜单等功能,当然设置密码不可见是必须的!

    下面介绍两种方式来实现相同的效果。

    效果

    这里写图片描述

    基础部分

    //设置无右键菜单
    setContextMenuPolicy(Qt::NoContextMenu);
    
    //设置无输入时提示信息
    setPlaceholderText(QStringLiteral("请输入密码"));
    
    //设置密码效果模式
    setEchoMode(QLineEdit::Password);
    
    //设置最大输入长度16位
    setMaxLength(16);

    enum QLineEdit::EchoMode

    这个枚举值描述输入框如何显示内容。

    常数 描述
    QLineEdit::Normal 0 输入时,正常显示字符,默认值
    QLineEdit::NoEcho 1 不显示任何信息,密码长度、信息需要保密时比较适用
    QLineEdit::Password 2 显示平台相关的密码掩码字符,而非实际的字符输入
    QLineEdit::PasswordEchoOnEdit 3 编辑时候显示字符,编辑结束后和QLineEdit::Password效果一样

    事件过滤器

    接口说明

    首先看下接口说明:

    void QObject::installEventFilter(QObject * filterObj)

    为对象安装一个filterObj事件过滤器,例如:

    monitoredObj->installEventFilter(filterObj);

    事件过滤器对象接受发送到被观察者对象的所有事件,可以停止事件或将其转发到被观察者对象。事件过滤器对象通过eventFilter() 来接受事件,如果指定的事件被过滤则必须返回true,否则返回false。

    如果一个对象安装多个事件过滤器,那么,最后安装的过滤器首先被激活。

    警告:如果在eventFilter()函数中删除接收对象,一定要返回true。如果返回false,Qt给已删除的对象发送事件,程序会crash。

    注意,过滤器对象必须和被观察者对象处于同一线程。如果过滤器对象在不同的线程,这个函数什么都不做。如果在调用这个函数之后,过滤器对象或被观察者对象被移动到不同的线程,事件过滤器将不会被调用,直到两个对象再处于相同的线程中。

    实现方式

    首先,需要判断被观察的对象,也就是这里的obj,我们观察的是密码框QLineEdit,所以先进行转换。

    然后进行事件判断与转换:鼠标移动对应的事件类型为mouseMoveEvent,鼠标双击对应的事件类型为mouseDoubleClickEvent,全选、复制、粘贴对应的事件类型为keyPressEvent,当接收到这些事件时,需要被过滤掉,所以返回true。

    注意:return QObject::eventFilter(obj, event)这句代码很关键,这里的意思是继续传递该事件到被观察者,由其本身调用相应的事件。

    bool EventFilter::eventFilter(QObject *obj, QEvent *event)
    {
        QLineEdit *pLineEdit = qobject_cast<QLineEdit *>(obj);
        if (pLineEdit != NULL)
        {
            switch (event->type())
            {
            case QEvent::MouseMove:  //鼠标移动事件
            case QEvent::MouseButtonDblClick:  //鼠标双击事件
                return true;
            case QEvent::KeyPress:  //键盘事件
            {
                QKeyEvent *pKeyEvent = static_cast<QKeyEvent*>(event);
                if(pKeyEvent->matches(QKeySequence::SelectAll)
                        || pKeyEvent->matches(QKeySequence::Copy)
                        || pKeyEvent->matches(QKeySequence::Paste))
                {
                    return true;
                }
            }
            }
        }
        return QObject::eventFilter(obj, event);
    }

    事件重写

    这种方式可能是大多数人都能想到的,针对输入框重新实现(PasswordLineEdit继承于QLineEdit)。

    如上,我们分析得出鼠标移动对应的事件类型为mouseMoveEvent,鼠标双击对应的事件类型为mouseDoubleClickEvent,全选、复制、粘贴对应的事件类型为keyPressEvent,那么我们重写相应的事件即可。

    //屏蔽输入框全选、复制、粘贴功能
    void PasswordLineEdit::keyPressEvent(QKeyEvent *event)
    {
        if(event->matches(QKeySequence::SelectAll)
                || event->matches(QKeySequence::Copy)
                || event->matches(QKeySequence::Paste))
        {
            return;
        }
    
        QLineEdit::keyPressEvent(event);
    }
    
    //鼠标位于密码框中时不可移动
    void PasswordLineEdit::mouseMoveEvent(QMouseEvent *event)
    {
        Q_UNUSED(event);
    }
    
    //鼠标双击密码框时不可选中
    void PasswordLineEdit::mouseDoubleClickEvent(QMouseEvent *event)
    {
        Q_UNUSED(event);
    }

    源码下载

  • 相关阅读:
    Service Cloud 零基础(五)Trailhead学习 Embedded Chat
    Community Cloud零基础学习(五)Topic(主题)管理
    Service Cloud 零基础(四)快速配置一个问卷调查(无开发)
    salesforce零基础学习(一百)Mobile Device Tracking
    mysql 设置查询超时配置
    YIi2 Object 报错问题
    php 如何创建uuid
    mysql8 安装后无法登录的问题
    nano编辑器保存退出
    在使用openbms的时候发现的Thinkphp action 大小写问题
  • 原文地址:https://www.cnblogs.com/itrena/p/5938405.html
Copyright © 2011-2022 走看看