关于验证码
- 验证码必须随机生成。
- 验证码必须有一定的识别难度。
关于解决方案
- 随机产生目标验证码。
- 验证码中的字符颜色随机变化。
- 在验证码区域随机绘制噪点。
- 利用已有组件进行重新实现。
效果:
头文件
class Verification : public QPushButton
{
Q_OBJECT
public:
explicit Verification(QWidget *parent = nullptr);
/*****************************************************************
* 函数名称: getColor()
* 功能描述: 随机挑选颜色
* 参数说明: 无
* 返回值: 返回颜色
******************************************************************/
Qt::GlobalColor* getColor();
//虚函数 接收绘制事件
void paintEvent(QPaintEvent *event);
QString m_captcha;
Qt::GlobalColor* m_color;
QTimer *m_timer;
signals:
public slots:
/*****************************************************************
* 函数名称: getCaptcha()
* 功能描述: 产生验证码
* 参数说明: 无
* 返回值: 无
******************************************************************/
QString getCaptcha();
/*****************************************************************
* 函数名称: TimeoutSlot()
* 功能描述: 如果图片被点击,就更新
* 参数说明: 无
* 返回值: 无
******************************************************************/
void TimeoutSlot();
};
源码:
Verification::Verification(QWidget *parent) : QPushButton(parent)
{
m_timer = new QTimer(this);
//QTime::currentTime()获取当前时间 QTime::currentTime().msec()是取时间作为产生随机数的种子.
qsrand(QTime::currentTime().second() * 1000 + QTime::currentTime().msec());
m_captcha = getCaptcha();//产生新的验证码
m_color = getColor();//产生新的颜色
connect(m_timer,SIGNAL(timeout()),this,SLOT(TimeoutSlot()));//如果图片被点击则产生新的颜色
m_timer->start(200);//每200微秒变化一次颜色
connect(this,SIGNAL(clicked(bool)),this,SLOT(getCaptcha()));//如果图片被点击则产生新的验证码
}
/*****************************************************************
* 函数名称: getCaptcha()
* 功能描述: 产生验证码
* 参数说明: 无
* 返回值: 无
******************************************************************/
QString Verification::getCaptcha()
{
QString ret = "";
for(int i = 0; i < 4; i++){
int c = (qrand() % 2) ? 'a' : 'A';
ret += static_cast<QChar>(c + qrand() % 26);
}
m_captcha = ret;
return ret;
}
/*****************************************************************
* 函数名称: getColor()
* 功能描述: 随机挑选颜色
* 参数说明: 无
* 返回值: 返回颜色
******************************************************************/
Qt::GlobalColor *Verification::getColor()
{
static Qt::GlobalColor colors[4];//定义填充样式的颜色
for(int i = 0; i < 4; i++)
{
//static_cast< new_type >(expression) 类似于C语言中的强制转化,该运算符把expression转换为new_type类型
colors[i] = static_cast<Qt::GlobalColor>((qrand() % 16) + 2);
}
return colors;
}
//虚函数 接收绘制事件
void Verification::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.fillRect(0, 0, 84, 24, Qt::white);//背景设为白色
painter.setFont(QFont("Comic Sans MS"));
//绘制噪点
for(int i = 0; i < 100; i++){
painter.setPen(m_color[i % 4]);
painter.drawPoint(0 + (qrand() % 84), 0 + (qrand() % 24));
}
//绘制验证码
for(int i = 0; i < 4; i++){
painter.setPen(m_color[i]);
painter.drawText(0 + 20 * i, 0, 20, 24, Qt::AlignCenter, QString(m_captcha[i]));
}
}
/*****************************************************************
* 函数名称: TimeoutSlot()
* 功能描述: 如果图片被点击,就更新
* 参数说明: 无
* 返回值: 无
******************************************************************/
void Verification::TimeoutSlot()
{
m_color = getColor();
update();
}
添加到页面中:
//将验证码放到界面中
captchaButton = new Verification(this);
captchaButton -> setGeometry(360,130,80,60);//设置控件位置以及大小
captchaLable = new QLabel(this);
captchaLable -> setGeometry(90,120,50,20);
captchaLable -> setText("验证码");
captchaLable -> setFont(flable);
captchaLine = new QLineEdit(this);
captchaLine -> setGeometry(150,120,200,40);
captchaLine -> setPlaceholderText("请输入4位验证码");
captchaLine -> setMaxLength(4);//设置长度为4
captchaLine->setFont(ft);
captchaLine->setValidator(new QRegExpValidator(QRegExp("^[A-Za-z]{4}$")));