天天看点

QT之登录对话框验证码

有时候在登录界面需要验证码功能,这样能够防止被恶意程序攻击,验证码必须动态随机产生,并且有一定的识别难度。

解决方案:

1.随机产生验证码

2.在验证码区域绘制噪声

3.验证码颜色随机变化

4.继承已有QLabel控件进行重绘

随机产生验证码:

for (int i = ; i < letter_number; ++i)   //letter_number为验证码位数
        verificationCode[i] = produceRandomLetter(); //函数里面随机产生一个数字 大小写字母
           

随机生成颜色:

for (int i = ; i < letter_number; ++i)
        verificationCode[i] = produceRandomLetter();
           

绘制噪声:

for (int j = ; j < noice_point_number; ++j)  //noice_point_number噪声点数
    {
        p.setX(qrand() % this->width());
        p.setY(qrand() % this->height());
        painter.setPen(colorArray[j % ]);
        painter.drawPoint(p);
    }
           

代码:

verificationcodelabel.h
#ifndef VERIFICATIONCODELABEL_H
#define VERIFICATIONCODELABEL_H
#include <QLabel>

class VerificationCodeLabel : public QLabel
{
    Q_OBJECT

public:
    VerificationCodeLabel(QWidget *parent=);
    ~VerificationCodeLabel();
    //返回一个字符串(字母一律都按照大写返回)
    QString getVerificationCode() const;
public slots:
    //公共槽函数
    //刷新验证码,在用户不确定的时候进行相应刷新
    void slt_reflushVerification();
protected:
    //重写绘制事件,以此来生成验证码
    void paintEvent(QPaintEvent *event);
private:
    const int letter_number = ;//产生字符的数量
    int noice_point_number ;//噪点的数量
    enum {  //枚举分类,也可自己定义
        NUMBER_FLAG,
        UPLETTER_FLAG,
        LOWLETTER_FLAG
    };
    //这是一个用来生成验证码的函数
    void produceVerificationCode() const;
    //产生一个随机的字符
    QChar produceRandomLetter() const;
    //产生随机的颜色
    void produceRandomColor() const;

    QChar *verificationCode;
    QColor *colorArray;
};


#endif // VERIFICATIONCODELABEL_H
           
verificationcodelabel.cpp
#include "verificationcodelabel.h"
#include <QPaintEvent>
#include <QPainter>
#include <QTime>
VerificationCodeLabel::VerificationCodeLabel(QWidget *parent)
    : QLabel(parent)
{
    //生成随机种子
    qsrand(QTime::currentTime().second() *  + QTime::currentTime().msec());
    colorArray = new QColor[letter_number];
    verificationCode = new QChar[letter_number];
    noice_point_number = this->width();
}
//重写绘制事件,以此来生成验证码
void VerificationCodeLabel::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    QPoint p;
    //背景设为白色
    painter.fillRect(this->rect(), Qt::white);
    //产生4个不同的字符
    produceVerificationCode();
    //产生4个不同的颜色
    produceRandomColor();
    //绘制验证码
    for (int i = ; i < letter_number; ++i)
    {
        p.setX(i*(this->width() / letter_number)+this->width()/);
        p.setY(this->height() / );
        painter.setPen(colorArray[i]);
        painter.drawText(p, QString(verificationCode[i]));
    }
    //绘制噪点
    for (int j = ; j < noice_point_number; ++j) //noice_point_number噪声点数
    {
        p.setX(qrand() % this->width());
        p.setY(qrand() % this->height());
        painter.setPen(colorArray[j % ]);
        painter.drawPoint(p);
    }
    return;
}
//这是一个用来生成验证码的函数
void VerificationCodeLabel::produceVerificationCode() const
{
    for (int i = ; 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() % ; break;
    case UPLETTER_FLAG:c='A' + qrand() % ; break;
    case LOWLETTER_FLAG:c='a' + qrand() % ; break;
    default:c=qrand() %  ? 'W' : 'D';
    }
    return c;
}
//产生随机的颜色
void VerificationCodeLabel::produceRandomColor() const
{
    for (int i = ; i < letter_number; ++i)
        colorArray[i] = QColor(qrand() % , qrand() % , qrand() % );
    return;
}
//返回一个字符串(字母一律都按照大写返回)
QString VerificationCodeLabel::getVerificationCode() const
{
    QString s;
    QChar cTemp;
    for (int i = ; i < letter_number; ++i)
    {
        cTemp = verificationCode[i];
        s += cTemp>?cTemp.toUpper():cTemp;
    }
    return s;
}
//刷新验证码,在用户不确定的时候进行相应刷新
void VerificationCodeLabel::slt_reflushVerification()
{
    repaint();
}
VerificationCodeLabel::~VerificationCodeLabel()
{

}
           

在.ui界面将对应的QLabel类对象提升为当前类即可

继续阅读