QtQML隨機驗證碼

使用 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()全部轉成小寫貨大寫對比
實現過程比較簡單,可以根據需要修改,比如加入動態字符等

發佈了18 篇原創文章 · 獲贊 4 · 訪問量 3062
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章