【Qt5】继承QWidget写一个验证码控件

先说下功能:就是简单以的四位数字+字母组合的验证码,控件的宽度会被锁定最少为高度的两倍(如果宽度少于高度的两倍,高度会被强制缩小至宽度的二分之一)。整个widget的区域会平分为4份来绘制字符(防止覆盖了),字符会以随机的大小(有最小限制)、随机的比例(拉伸比例有最小限制,高度不得低于宽度的三分之一,拉太扁就看不清了(╯‵□′)╯︵┻━┻)、随机的旋转角度(不会转出区域外且最大顺逆时针转4...
摘要由CSDN通过智能技术生成

先说下功能:

就是简单以的四位数字+字母组合的验证码,控件的宽度会被锁定最少为高度的两倍(如果宽度少于高度的两倍,高度会被强制缩小至宽度的二分之一)。

整个widget的区域会平分为4份来绘制字符(防止覆盖了),字符会以随机的大小(有最小限制)、随机的比例(拉伸比例有最小限制,高度不得低于宽度的三分之一,拉太扁就看不清了(╯‵□′)╯︵┻━┻)、随机的旋转角度(不会转出区域外且最大顺逆时针转45°)在对应区域的随机位置出现。

拉伸策略可以设置为preferred,不过直接拉伸的话是将当前的图直接放大,重新刷新才会根据当前长宽重新绘制。具体看图吧

写的有点复杂也有点乱,裁剪Image那个效率有点低,不得不降低图片大小以及跳行遍历来提升效率,欢迎指正或意见。

或许之后会另外一篇来讲下每个方法思路?(如果都看不懂的话(╯‵□′)╯︵┻━┻)

下面就贴下源码

头文件Vf_widget.h

#ifndef VF_WIDGET_
#define VF_WIDGET_

#include <QtWidgets>
#include <QtGlobal>
#include <QPainter>
#include <QEvent>
#include <QTime>
#include <QFont>
#include <QFontDatabase>
#include <QStringList>
#include <QImage>
#include <cmath>

#define Vf_PI 3.141592654

class Vf_widget : public QWidget
{
	Q_OBJECT

signals:
	void result(bool result);
signals:
	void flash_code();
signals:
	void getCaption(QChar* p_cap);

public:
	typedef enum {
		Just_accept,	//仅接受鼠标点击事件但不作处理
		Click_left,		//左键单击刷新
		Click_right,	//右键
		Double_left,	//左键双击刷新
		Double_right,	//右键双击
		Ignore_click	//忽略鼠标点击事件,传递给父组件
	}Flash_mode;

	typedef enum {
		Allow,
		Prohibit
	}Opinion;

	struct For_var{
		For_var() {};
		~For_var() { 
			if (img_char != NULL) delete img_char; 
			if (fm_text != NULL) delete fm_text;
		};
		QPainter painter_font;	//绘制单个字符到QImge的画笔
		QPoint p_topleft;		//当前绘制字符的初始位置的左上角坐标
		QRect r_font;			//当前字符的rect,控制字符大小及拉伸情况等
		qreal diagonal;			//当前rect的对角线长度,单位是pixel
		qreal max_angle;		//当前rect的最大可旋转弧度(顺时针)
		qreal min_angle;		//当前rect的最大可旋转弧度(逆时针)
		qreal d_angle;			//对角线diagnoal与当前rect的高(r_font.height)的夹角弧度
		int l_size;				//p_topleft距离左边缘的长度
		int r_size;				//p_topleft距离右边缘的长度
		int font_angle;			//当前绘制字符的旋转角度(非弧度)
		QFont f_text;			//文本字体
		QFontMetrics *fm_text;	//获取font的大小等参数
		QImage *img_char;		//绘制当前字符
	};//绘制验证码的循环体内需要用到的变量

	Vf_widget(int width = 360, int height = 90, Flash_mode mode = Just_accept, QWidget *parent = Q_NULLPTR);
	~Vf_widget();

	void setFlash_mode(Flash_mode mode);
	void reflash();
	bool check(QString caption);

protected:
	void paintEvent(QPaintEvent *e);
	void mousePressEvent(QMouseEvent *e);
	void mouseDoubleClickEvent(QMouseEvent *e);
	void resizeEvent(QResizeEvent *e);

private:
	int width;
	int height;
	typename Vf_widget::Flash_mode mode;
	typename Vf_widget::Opinion flash_opinion;

	Qt::GlobalColor color[4];
	QChar caption[5];
	QStringList *fon
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值