使用 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()全部转成小写货大写对比
实现过程比较简单,可以根据需要修改,比如加入动态字符等