QtQML随机验证码

2 篇文章 0 订阅

使用 QPainter 绘图,从 QQuickPaintedItem 继承,重写 paint() ,通过C++实现QML可视图元;
QPainter绘图数据(验证码,颜色,干扰等)通过随机数获取;

1、效果
在这里插入图片描述

2、实现类

#ifndef ZOLVERIFICATIONCODE_H
#define ZOLVERIFICATIONCODE_H
#include<QQuickPaintedItem>

class ZolVerificationCode : public QQuickPaintedItem
{
   Q_OBJECT
   Q_PROPERTY(QString verification READ verification WRITE setVerification NOTIFY verificationChanged)
public:
    ZolVerificationCode();

    void paint(QPainter* painter);
    void drawCode(QPainter* painter);
    QString getVerificationCode();

public:
   //刷新验证码
   Q_INVOKABLE void slt_reflushVerification();

   void setVerification(const QString &verification){m_verificationCode = verification;}
   QString verification() const {return m_verificationCode;}

signals:
   void verificationChanged();

private:
    int letter_number = 4;//字符数
    int noice_point_number ;//干扰点数
    //生成验证码
    void produceVerificationCode() const;
    //产生随机字符
    QChar produceRandomLetter() const;
    //产生随机颜色
    void produceRandomColor() const;

    QChar *verificationCode;
    QColor *colorArray;
    QString m_verificationCode;
    int m_width;
    int m_height;
};

#endif // ZOLVERIFICATIONCODE_H

#include "zolverificationcode.h"
#include <QTime>
#include <QPainter>

ZolVerificationCode::ZolVerificationCode()
{
    setAntialiasing(true);
    //生成随机种子
    qsrand(QTime::currentTime().second() * 1000 + QTime::currentTime().msec());
    colorArray = new QColor[letter_number];
    verificationCode = new QChar[letter_number];

}

void ZolVerificationCode::paint(QPainter *painter)
{
    m_width = contentsBoundingRect().width();
    m_height = contentsBoundingRect().height();
    noice_point_number = m_width * 1.5;
    double m_scale = 1;
    painter->scale(m_scale,m_scale);

    //产生4个不同的字符
    qsrand(QTime::currentTime().second() * 1000 + QTime::currentTime().msec());
    produceVerificationCode();
    QString verification="";
    for (int i = 0; i < letter_number; ++i){
        verification = verification + verificationCode[i];
        setVerification(verification);
    }
    //产生4个不同的颜色
    produceRandomColor();
    drawCode(painter);

}

void ZolVerificationCode::drawCode(QPainter *painter)
{
    painter->save();
    QPointF p;
    //绘制验证码
    QFont textFont;
    textFont.setPixelSize(36);
    textFont.setStyle(QFont::StyleOblique);

    for (int i = 0; i < letter_number; ++i)
    {
        p.setX(i*(m_width / letter_number)+ m_width / 16);
        p.setY(m_height / 3  + qrand() % (m_height / 2 ));
        painter->setPen(colorArray[i]);
        painter->setFont(textFont);
        painter->drawText(p, QString(verificationCode[i]));
    }
    //绘制干扰点
    for (int j = 0; j < noice_point_number; ++j) //noice_point_number点数
    {
        painter->setPen(colorArray[j % 4]);
        painter->setBrush(colorArray[j % 4]);
        QRect pointRect(qrand() % m_width,qrand() % m_height,2,2);
        painter->drawEllipse(pointRect);
    }
    //绘制干扰线
    for (int i = 0; i < letter_number; ++i)
    {
        p.setX(i*(m_width / letter_number)+ m_width / 8);
        p.setY(m_height / 2);

        QPainterPath anhuipath;
        anhuipath.moveTo( qrand() % m_width , qrand() % m_height);
        anhuipath.lineTo( qrand() % m_width , qrand() % m_height);
        anhuipath.setFillRule(Qt::WindingFill);
        painter->setPen(QPen(colorArray[i], 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
        painter->drawPath(anhuipath);
    }
    painter->restore();
    emit verificationChanged();
}

QString ZolVerificationCode::getVerificationCode()
{
    QString str;
    QChar cTemp;
    for (int i = 0; i < letter_number; ++i)
    {
        cTemp = verificationCode[i];
        str += cTemp > 97 ? cTemp.toUpper():cTemp;
    }
    return str;
}

void ZolVerificationCode::slt_reflushVerification()
{
    update();
}

void ZolVerificationCode::produceVerificationCode() const
{
    QString verifiStr = "";
    for (int i = 0; i < letter_number; ++i){
        verificationCode[i] = produceRandomLetter();
    }
    return;
}

QChar ZolVerificationCode::produceRandomLetter() const
{
    QChar c;
    int flag = qrand() % letter_number;
    switch (flag)
    {
        case 0: c='0' + qrand() % 10; break;
        case 1: c='A' + qrand() % 26; break;
        case 2: c='a' + qrand() % 26; break;
        default: c='0' + qrand() % 10; break;
    }
    return c;
}

void ZolVerificationCode::produceRandomColor() const
{
    for (int i = 0; i < letter_number; ++i)
           colorArray[i] = QColor(qrand() % 255, qrand() % 255, qrand() % 255);
       return;
}

3、注册
qmlRegisterType(uri, 1, 0, “ZolVerificationCode”);

4、
使用

                            Rectangle{
                                id:verificationPainter
                                width: parent.width - 40 * m_ratio
                                height: parent.height
                                anchors.left: parent.left
                                anchors.top: parent.top
                                radius: radius_real
                                ZolVerificationCode{
                                    id: verificationItem
                                    anchors.left: parent.left
                                    anchors.top: parent.top
                                    anchors.right: parent.right
                                    anchors.bottom: parent.bottom
                                }
                            }
//******************************************************************//
//刷新
    Connections{
        target: verchange
        onClicked:{
            verificationItem.slt_reflushVerification()
        }
    }
    //******************************************************************//
    //获取字符
        Connections{
        target: verificationItem
        onVerificationChanged:{
             _Putvercode = verificationItem.verification
        }
    }

注意:对比时可用verificationCodeText.text.toLowerCase()全部转成小写货大写对比
实现过程比较简单,可以根据需要修改,比如加入动态字符等

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值