有时候在登录界面需要验证码功能,这样能够防止被恶意程序攻击,验证码必须动态随机产生,并且有一定的识别难度。
解决方案:
1.随机产生验证码
2.在验证码区域绘制噪声
3.验证码颜色随机变化
4.继承已有QLabel控件进行重绘
随机产生验证码:
for (int i = 0; i < letter_number; ++i) //letter_number为验证码位数
verificationCode[i] = produceRandomLetter(); //函数里面随机产生一个数字 大小写字母
随机生成颜色:
for (int i = 0; i < letter_number; ++i)
verificationCode[i] = produceRandomLetter();
绘制噪声:
for (int j = 0; j < noice_point_number; ++j) //noice_point_number噪声点数
{
p.setX(qrand() % this->width());
p.setY(qrand() % this->height());
painter.setPen(colorArray[j % 4]);
painter.drawPoint(p);
}
代码:
verificationcodelabel.h
#ifndef VERIFICATIONCODELABEL_H
#define VERIFICATIONCODELABEL_H
#include <QLabel>
class VerificationCodeLabel : public QLabel
{
Q_OBJECT
public:
VerificationCodeLabel(QWidget *parent=0);
~VerificationCodeLabel();
//返回一个字符串(字母一律都按照大写返回)
QString getVerificationCode() const;
public slots:
//公共槽函数
//刷新验证码,在用户不确定的时候进行相应刷新
void slt_reflushVerification();
protected:
//重写绘制事件,以此来生成验证码
void paintEvent(QPaintEvent *event);
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;
};
#endif // VERIFICATIONCODELABEL_H
verificationcodelabel.cpp
#include "verificationcodelabel.h"
#include <QPaintEvent>
#include <QPainter>
#include <QTime>
VerificationCodeLabel::VerificationCodeLabel(QWidget *parent)
: QLabel(parent)
{
//生成随机种子
qsrand(QTime::currentTime().second() * 1000 + 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 = 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]));
}
//绘制噪点
for (int j = 0; j < noice_point_number; ++j) //noice_point_number噪声点数
{
p.setX(qrand() % this->width());
p.setY(qrand() % this->height());
painter.setPen(colorArray[j % 4]);
painter.drawPoint(p);
}
return;
}
//这是一个用来生成验证码的函数
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;
}
//刷新验证码,在用户不确定的时候进行相应刷新
void VerificationCodeLabel::slt_reflushVerification()
{
repaint();
}
VerificationCodeLabel::~VerificationCodeLabel()
{
}
在.ui界面将对应的QLabel类对象提升为当前类即可