小成开发日记----利用Qt/C++实现验证码功能

一、前言

作者:小成Charles
转载请标注作者原链接:https://blog.csdn.net/weixin_42999453/article/details/109709684

今天没事用Qt写了一个验证码模块的demo,平时很少用Qpainter,这次就做了这个demo练练手,话不多说直接上图看效果
在这里插入图片描述

二、分析

做这种的效果主要是弄清楚坐标的位置关系以及paintEvent事件的灵活运用
(1)分析坐标
为了方便理解我画了一张图如下,要注意的一点就是当前矩形的x,y坐标的起点位置是左上角点,其中ABCD使我们需要的坐标位置来存放验证码的位置,这样均分看起来就比较美观嘛,第一个字符X坐标为(x+w/4)/2,依此类推,他们之间相差的距离都为w/2。然后Y坐标就是固定的(y+h)/2,这样每一个字符的坐标位置就很明确了;
在这里插入图片描述

(2)paintEvent事件分析
其中有一些注意点像我这样的小白玩家需要注意:

  1. painEvent中如果需要创建多个Qpainter对象时,需要将前一个Qpainter对象end,才能进行下一个Qpainter对象,不然无法加载下一个!
  2. painEvent事件中不要做一些数据存储的代码块,因为非Qpainter类下的代码块会被重复运行,我就是因为在里面写随机数获取存储的内容被重复运行,然后导致我最后验证码数据和图片不匹配,所以尽量在外部把数据处理好了再传到paintEvent里面去

三、上代码!

mainWindow.h 头文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPaintEvent>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    void paintEvent(QPaintEvent *e);
    void paintDots();//画背景点
    void drawChars();//画字符
    QString textCode="初始化验证码";
    QString chrs= "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";//字符集
    void getRandchar();//获取随机字符
    ~MainWindow();

private slots:


    void on_btnChange_2_clicked();

    void on_btnVretifiy_clicked();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

这里是画背景的代码块paintDots(),实现了各色随机的点

void MainWindow::paintDots()
{

    int maxPosX=ui->label->pos().x()+ui->label->width();
    int minPosX=ui->label->pos().x();
    int maxPosY=ui->label->pos().y()+ui->label->height();
    int minPosY=ui->label->pos().y();
    //画点
    QPainter *painterPoints=new QPainter;
    painterPoints->begin(this);
    QPen pen;
    QBrush brush;
    brush.setColor(Qt::white);
    brush.setStyle(Qt::SolidPattern);
    painterPoints->setBrush(brush);
    painterPoints->drawRect(QRect( ui->label->pos(),QPoint(maxPosX,maxPosY)));
    QColor color;
    pen.setWidth(3);
    pen.setStyle(Qt::DotLine);
    //    qDebug()<<maxPosX<<maxPosY;
    QPoint *points=new QPoint[500];
    for (int i=0;i<300;i++) {
        points[i]=QPoint(qrand()%(maxPosX-minPosX)+minPosX,qrand()%(maxPosY-minPosY)+minPosY);
        int R=qrand()%255;
        int G=qrand()%255;
        int B=qrand()%255;
        color.setRgb(R,G,B);
        pen.setColor(color);
        painterPoints->setPen(pen);
        painterPoints->drawPoint(points[i]);

    }
    painterPoints->end();
}

这里是drawChars(),实现了在图中华出四个随机的字符,且每个字符的颜色都不一样

void MainWindow::drawChars()
{//画字符
    qreal labelWidth=ui->label->width();
    qreal labelHeight=ui->label->height();
    qreal labelx=ui->label->pos().x();
    qreal labely=ui->label->pos().y();
    int maxPosX=ui->label->pos().x()+ui->label->width();
    int maxPosY=ui->label->pos().y()+ui->label->height();
    QRect rect( ui->label->pos(),QPoint(maxPosX,maxPosY));
    QPainter *painter=new QPainter;
    painter->begin(this);
    QFont font;
    QPen pen;
    pen.setWidth(3);
    font.setPointSize(20);
    font.setBold(true);
    painter->setFont(font);
    //画随机字符
    for(int i=0;i<4;i++)
    {

        //        qDebug()<<str;
        int R=qrand()%255;
        int G=qrand()%255;
        int B=qrand()%255;
        QColor color;
        color.setRgb(R,G,B);
        pen.setColor(color);
        painter->setPen(pen);
        QPointF pointF;
        pointF.setX(labelx+(labelWidth/7+(labelWidth/4)*(i*2))/2);
        pointF.setY(labely+(labelHeight/1.5));
        //        qDebug()<<pointF;
        //        int randomx=qrand()%(chrs.length()-1);
        painter->drawText(pointF,textCode.at(i));
        //        textCode.append(textCode.at(i));
     
    }

    painter->end();
}.

接下来就是paintEvent中调用这两个函数,依次画图合成了验证码,利用update()可以实现验证码的刷新,这里注意,因为获取随机验证码字符串是在外部函数实现的,更新的时候需要将getRandchar()调用一下

void MainWindow::getRandchar()
{

    textCode.clear();

    int chrs_size = chrs.length();//字符集数组长度

    for(int i=0;i<4;i++)
    {
        int randomx=qrand()%(chrs_size-1);
        QString str =  chrs.at(randomx);
        textCode.append(str);
    }
    qDebug()<<textCode;
}

void MainWindow::paintEvent(QPaintEvent *e)
{
    paintDots();
    drawChars();
}



void MainWindow::on_btnChange_2_clicked()
{
    //
    getRandchar();
    this->update();
}

void MainWindow::on_btnVretifiy_clicked()
{
    if(textCode==ui->lineEdit->text())
    {
        QMessageBox::information(this,"right","验证码正确");
        qDebug()<<"正确";
    }else {
        QMessageBox::information(this,"right","验证码错误");
        qDebug()<<"错误";
    }
}

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值