Qt中生成验证码

简述

Qt生成验证码功能,借鉴与下面的博主,加以修改。

先看原文再看下面解决的问题.

原文链接:https://blog.csdn.net/wjh_init/article/details/79163275

解决的问题

1.解决窗口拖动影响验证码重新生成
2.增加鼠标左键单击更新验证码

头文件

#ifndef VERIFICATIONCODELABEL_H
#define VERIFICATIONCODELABEL_H
这是一个继承QLabel从而用来实现验证码功能的标签
#include <QLabel>

class VerificationCodeLabel : public QLabel
{
    Q_OBJECT

public:
    VerificationCodeLabel(QWidget *parent=0);
    ~VerificationCodeLabel();
    //返回一个字符串(字母一律都按照大写返回)
    QString getVerificationCode() const;
protected:
    //重写绘制事件,以此来生成验证码
    void paintEvent(QPaintEvent *event);
    void mouseReleaseEvent(QMouseEvent *ev);
private:
    const int letter_number = 4;//产生字符的数量
    int noice_point_number ;//噪点的数量
    enum {
        NUMBER_FLAG,
        UPLETTER_FLAG,
        LOWLETTER_FLAG
    };
    //这是一个用来生成验证码的函数
    void produceVerificationCode() const;
    //产生一个随机的字符
    QChar produceRandomLetter() const;
    //产生随机的颜色
    void produceRandomColor() const;

    QChar *verificationCode;
    QColor *colorArray;
    bool temp;

    //保留上一次噪点位置
    QList<int> ListX;
    QList<int> ListY;
};

#endif // VERIFICATIONCODELABEL_H

cpp文件

#include "verificationcodelabel.h"
#include <QPaintEvent>
#include <QPainter>
#include <QTime>
VerificationCodeLabel::VerificationCodeLabel(QWidget *parent)
    : QLabel(parent)
    , temp(true)
{
    //生成随机种子
    qsrand(QTime::currentTime().second() * 1000 + QTime::currentTime().msec());
    colorArray = new QColor[letter_number];
    verificationCode = new QChar[letter_number];
    //noice_point_number 可控制模糊度,越高越不易看出验证码
    noice_point_number = this->width() * 2;
}

VerificationCodeLabel::~VerificationCodeLabel()
{

}

//重写绘制事件,以此来生成验证码
void VerificationCodeLabel::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    QPainter painter(this);
    QPoint p;
    //背景设为白色
    painter.fillRect(this->rect(), Qt::white);
    if (temp) {
        //产生4个不同的字符
        produceVerificationCode();
        //产生4个不同的颜色
        produceRandomColor();
        //删除上次噪点
        ListX.clear();
        ListY.clear();
        //绘制噪点后保存
        for (int j = 0; j < noice_point_number; ++j) {
            ListX.append(qrand());
            ListY.append(qrand());
            p.setX(ListX.at(j) % this->width());
            p.setY(ListY.at(j) % this->height());
            painter.setPen(colorArray[j % 4]);
            painter.drawPoint(p);
        }
    }

    //绘制上次保存的噪点
    for (int j = 0; j < noice_point_number; ++j) {
        p.setX(ListX.at(j) % this->width());
        p.setY(ListY.at(j) % this->height());
        painter.setPen(colorArray[j % 4]);
        painter.drawPoint(p);
    }

    //绘制验证码
    for (int i = 0; i < letter_number; ++i) {
        p.setX(i*(this->width() / letter_number)+this->width()/8);
        p.setY(this->height() / 2);
        painter.setPen(colorArray[i]);
        painter.drawText(p, QString(verificationCode[i]));
    }

    temp = false;
}

void VerificationCodeLabel::mouseReleaseEvent(QMouseEvent *ev)
{
    //鼠标单击刷新
    if (ev->button() == Qt::LeftButton) {
        temp = true;
        repaint();
    }
}

//这是一个用来生成验证码的函数
void VerificationCodeLabel::produceVerificationCode() const
{
    for (int i = 0; i < letter_number; ++i) {
        verificationCode[i] = produceRandomLetter();
    }
    return;
}
//产生一个随机的字符
QChar VerificationCodeLabel::produceRandomLetter() const
{
    QChar c;
    int flag = qrand() % letter_number;
    switch (flag) {
    case NUMBER_FLAG:c='0' + qrand() % 10; break;
    case UPLETTER_FLAG:c='A' + qrand() % 26; break;
    case LOWLETTER_FLAG:c='a' + qrand() % 26; break;
    default:c=qrand() % 2 ? 'W' : 'D';
    }
    return c;
}

//产生随机的颜色
void VerificationCodeLabel::produceRandomColor() const
{
    for (int i = 0; i < letter_number; ++i) {
        colorArray[i] = QColor(qrand() % 255, qrand() % 255, qrand() % 255);
    }
    return;
}

//返回一个字符串(字母一律都按照大写返回)
QString VerificationCodeLabel::getVerificationCode() const
{
    QString s;
    QChar cTemp;
    for (int i = 0; i < letter_number; ++i) {
        cTemp = verificationCode[i];
        s += cTemp > 97 ? cTemp.toUpper():cTemp;
    }
    return s;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值