Qt 之密码框不可选中、复制、粘贴、无右键菜单等

简述

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

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

| 版权声明:一去、二三里,未经博主允许不得转载。

效果

这里写图片描述

基础部分

//设置无右键菜单
setContextMenuPolicy(Qt::NoContextMenu);

//设置无输入时提示信息
setPlaceholderText(QStringLiteral("请输入密码"));

//设置密码效果模式
setEchoMode(QLineEdit::Password);

//设置最大输入长度16位
setMaxLength(16);

enum QLineEdit::EchoMode

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

常数描述
QLineEdit::Normal0输入时,正常显示字符,默认值
QLineEdit::NoEcho1不显示任何信息,密码长度、信息需要保密时比较适用
QLineEdit::Password2显示平台相关的密码掩码字符,而非实际的字符输入
QLineEdit::PasswordEchoOnEdit3编辑时候显示字符,编辑结束后和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);
}

源码下载

  • 15
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
要实现只画选中右键选功能,可以通过以下步骤来实现: 1. 重载 `QGraphicsView` 的 `mousePressEvent` 和 `mouseReleaseEvent` 函数,记录鼠标按下和释放的位置,并在这两个位置之间绘制一个矩形选区域。 2. 在 `mouseReleaseEvent` 中获取选区域内的所有图形项,但不进行选中操作。 下面是一个简单的示例代码: ```cpp class MyGraphicsView : public QGraphicsView { public: MyGraphicsView(QWidget *parent = nullptr) : QGraphicsView(parent) {} protected: void mousePressEvent(QMouseEvent *event) override { if (event->button() == Qt::RightButton) { rubberBandStartPos = event->pos(); rubberBand = new QRubberBand(QRubberBand::Rectangle, this); rubberBand->setGeometry(QRect(rubberBandStartPos, QSize())); rubberBand->show(); } QGraphicsView::mousePressEvent(event); } void mouseReleaseEvent(QMouseEvent *event) override { if (event->button() == Qt::RightButton) { rubberBand->hide(); QRect rect = QRect(rubberBandStartPos, event->pos()).normalized(); QList<QGraphicsItem*> items = items(rect); // TODO: 处理选中的图形项 delete rubberBand; } QGraphicsView::mouseReleaseEvent(event); } private: QPoint rubberBandStartPos; QRubberBand *rubberBand = nullptr; }; ``` 在上面的代码中,我们首先在鼠标按下事件中记录了起始位置,并创建了一个 `QRubberBand` 对象,用于绘制矩形选区域。 在鼠标释放事件中,我们获取选区域内的所有图形项,并进行相应的处理。这里我们只是简单地将选中的图形项放到了一个 `QList` 中,你可以根据实际需求进行操作。 注意,这里我们调用了基类的 `mousePressEvent` 和 `mouseReleaseEvent` 函数,以确保其他事件的正常处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一去丶二三里

有收获,再打赏!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值