效果
功能
1、生成并绘制随机验证码
2、绘制随机噪点
3、颜色随机动态改变
源码
captchawidget.h:
#ifndef CAPTCHAWIDGET_H
#define CAPTCHAWIDGET_H
#include <QWidget>
#include<QPaintEvent>
#include<QTimer>
#include<QMouseEvent>
class CaptchaWidget : public QWidget
{
Q_OBJECT
public:
explicit CaptchaWidget(QWidget *parent = nullptr);
QString getCaptch() const;
void changeCode();
protected:
void paintEvent(QPaintEvent*event);
void mouseDoubleClickEvent(QMouseEvent*event);
signals:
private slots:
void onTimeOut();
private:
//左右上下内边距 默认为0
int m_leftMargin;
int m_rightMargin;
int m_topMargin;
int m_bottomMargin;
//单个验证码所在矩形的高和宽 默认为整个空间高/宽的90%四等分
int m_fontHeight;
int m_fontWidth;
Qt::GlobalColor* m_colors;
QString m_verification;
QTimer m_timer;
QString getVerificationCode();
Qt::GlobalColor *getColors();
};
#endif // CAPTCHAWIDGET_H
captchawidget.cpp:
#include "captchawidget.h"
#include<QTime>
#include<QPainter>
CaptchaWidget::CaptchaWidget(QWidget *parent)
: QWidget{
parent},m_timer(this),m_rightMargin(0)
,m_leftMargin(0),m_topMargin(0),m_bottomMargin(0)
{
m_fontHeight=height()-m_topMargin-m_bottomMargin;
m_fontWidth=(width()-m_leftMargin-m_rightMargin)/4;
//生成伪随机种子
qsrand(QTime::currentTime().second() * 1000 + QTime::currentTime().msec());
m_colors = getColors();
m_verification = getVerificationCode();
connect(&m_timer, SIGNAL(timeout()), this, SLOT(onTimeOut()));
//每0.5秒发出一次超时信号
m_timer.start(500);
}
void CaptchaWidget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
//填充验证码绘制矩形
painter.setFont(QFont("Comic Sans MS", 14));
//绘制验证码
int step=(width()-m_leftMargin-m_rightMargin)/4;
for(int i = 0; i <4; i++)
{
painter.setPen(m_colors[i]);
painter.drawText(m_leftMargin+step*i,m_topMargin,m_fontWidth, m_fontHeight, Qt::AlignCenter, QString(m_verification[i]));
}
//绘制噪点
for(int i=0; i<150; i++)
{
painter.setPen(m_colors[i%4]);
painter.drawPoint(qrand() %width() ,qrand() % height());
}
}
void CaptchaWidget::onTimeOut()
{
qsrand(QTime::currentTime().second() * 1000 + QTime::currentTime().msec());
m_colors = getColors();
//刷新 会触发重写的paintEvent但是这个不是立即重绘,而且只会重绘需要重绘的部分
update();
}
Qt::GlobalColor* CaptchaWidget::getColors()
{
//这里用了一个局部静态数组变量 那么这个函数就共用这个数组了
static Qt::GlobalColor colors[4];
for(int i=0; i<4; i++)
{
//Qt:GlobalColor的枚举值的范围是0~19 但是0和1是用于位图的 所以这里从2开始
//这里是将要产生的
colors[i] = static_cast<Qt::GlobalColor>(2 + qrand() % 16);
}
return colors;
}
//获取验证码
QString CaptchaWidget::getVerificationCode()
{
QString ret = "";
for(int i = 0; i < 4; i++)
{
int c = (qrand() % 2) ? 'a' : 'A';
ret += static_cast<QChar>(c + qrand() % 26);
}
return ret;
}
//双击验证码绘制矩形区域,生成新的验证码
void CaptchaWidget::mouseDoubleClickEvent(QMouseEvent *event)
{
m_verification = getVerificationCode();
//执行重绘,触发重写的绘制事件函数,而且是立即重绘整个页面
repaint();
}
QString CaptchaWidget::getCaptch() const
{
return m_verification;
}
void CaptchaWidget::changeCode()
{
m_verification = getVerificationCode();
//执行重绘,触发重写的绘制事件函数,而且是立即重绘整个页面
repaint();
}
结语
如果你觉得有用就给我点个赞吧