QT滑块图片验证程序

使用QT实现滑块验证程序,原理是画个图片,然后在图片上画个空白区域,再画个滑块图片。

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();
private:void initForm();void drawPicture();private slots:void onUpdateWidget();void onSliderValueChanged(int value);void onSliderReleased();void onUpdatePixmap();protected:bool eventFilter(QObject *watched, QEvent *event);void paintEvent(QPaintEvent *event);private:Ui::Widget *ui;QString m_pixmap;QPoint m_offsetPoint;int m_value;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QPaintEvent>
#include <QPainter>
#include <QPainterPath>
#include <QDebug>
#include <QMessageBox>
#include <QTimer>
#include <QSlider>
#include <QRandomGenerator>const int squarewidth = 46;
const int squareradius = 20;Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);this->setFixedHeight(600);this->setFixedWidth(800);m_value = 0;m_offsetPoint = QPoint(0, 0);ui->widget->installEventFilter(this);this->initForm();
}Widget::~Widget()
{delete ui;
}void Widget::initForm()
{QTimer::singleShot(10, this, SLOT(onUpdateWidget()));connect(ui->horizontalSlider, &QSlider::valueChanged, this, &Widget::onSliderValueChanged);connect(ui->horizontalSlider, &QSlider::sliderReleased, this, &Widget::onSliderReleased);m_pixmap = QString("H:\\picture\\TorchLight\\TorchLight0.bmp");QTimer::singleShot(100, this, SLOT(onUpdatePixmap()));}void Widget::onUpdateWidget()
{ui->horizontalSlider->setRange(0, ui->widget->width() - squarewidth);
}void Widget::onUpdatePixmap()
{m_offsetPoint.rx() = qBound(0, QRandomGenerator::global()->bounded(1024*10) % this->width() + squarewidth + squareradius,this->width() - squarewidth);m_offsetPoint.ry() = qBound(0, QRandomGenerator::global()->bounded(1024*10) % ui->widget->height() + squarewidth + squareradius,ui->widget->height() - squarewidth - squareradius);qDebug()<<m_offsetPoint.rx()<<m_offsetPoint.ry();this->update();
}void Widget::onSliderValueChanged(int value)
{//ui->widget->setValue(value);m_value = qBound(0, value, ui->widget->width() - squarewidth);update();
}void Widget::onSliderReleased()
{bool isOverlap = qAbs(-m_offsetPoint.x() + m_value) < 5;QString content = isOverlap ? "验证成功!" : "验证失败!";QMessageBox msgBox;msgBox.setWindowTitle("滑块图片验证");msgBox.setText(content);msgBox.exec();}void Widget::drawPicture()
{QPainter painter(ui->widget);painter.setRenderHint(QPainter::Antialiasing);QPainterPath clippath;clippath.addRoundedRect(ui->widget->rect(), 4, 4);painter.setClipPath(clippath);//画背景图const QPixmap & pixmap = QPixmap(m_pixmap).scaled(ui->widget->width(), ui->widget->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);painter.drawPixmap(0, 0, ui->widget->width(), ui->widget->height(), pixmap);QPainterPath cutoutpath;cutoutpath.setFillRule(Qt::WindingFill);QRect rect(m_offsetPoint, QSize(squarewidth, squarewidth));cutoutpath.addEllipse(rect);//画被扣除的空白区域QPainterPath subellipsepath;subellipsepath.addEllipse(rect.x(), rect.y() - rect.height() / 2, rect.width(), rect.height());cutoutpath = cutoutpath.united(subellipsepath);painter.setPen(QPen(QColor(80, 80, 80), 1));painter.setBrush(QColor(200, 200, 200, 220));painter.drawPath(cutoutpath);//画滑块图片QPixmap puzzlePixmap(ui->widget->size());puzzlePixmap.fill(Qt::transparent);QPainter puzzlePainter(&puzzlePixmap);puzzlePainter.setRenderHints(QPainter::Antialiasing);puzzlePainter.setClipPath(cutoutpath);puzzlePainter.setPen(QPen(QColor(229, 228, 228), 2));puzzlePainter.drawPixmap(0, 0, ui->widget->width(), ui->widget->height(), pixmap);puzzlePainter.drawPath(cutoutpath);painter.drawPixmap(-m_offsetPoint.x() + m_value, 0, ui->widget->width(), ui->widget->height(), puzzlePixmap);}bool Widget::eventFilter(QObject *watched, QEvent *event)
{if (watched == ui->widget && event->type() == QEvent::Paint){drawPicture();return true;}return QWidget::eventFilter(watched, event);
}void Widget::paintEvent(QPaintEvent *)
{}

QSlider的样式表

 QSlider::groove:horizontal {border: 1px solid #999999;height: 10px; /* the groove expands to the size of the slider by default. by giving it a height, it has a fixed size */background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #B1B1B1, stop:1 #c4c004);margin: 2px 0;}QSlider::handle:horizontal {background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #b4b4b4, stop:1 #8f0f8f);border: 1px solid #5c0c5c;width: 18px;margin: -12px 0; /* handle is placed by default on the contents rect of the groove. Expand outside the groove */border-radius: 3px;}

空白区域画法

在painter中绘制一个封闭的painterpath。path中的路径通过添加形状的方式自己设置。背景色通过setBrush设置。

QPainterPath cutoutpath;
cutoutpath.setFillRule(Qt::WindingFill);
QRect rect(m_offsetPoint, QSize(squarewidth, squarewidth));
cutoutpath.addEllipse(rect);//画被扣除的空白区域
QPainterPath subellipsepath;
subellipsepath.addEllipse(rect.x(), rect.y() - rect.height() / 2, rect.width(), rect.height());
cutoutpath = cutoutpath.united(subellipsepath);painter.setPen(QPen(QColor(80, 80, 80), 1));
painter.setBrush(QColor(200, 200, 200, 220));
painter.drawPath(cutoutpath);

滑块图片画法

注意puzzlePainter指向puzzlePixmap,puzzlePixmap是个透明图,在里面绘制同上方空白区域的painterpath可见,然后合并图片和空白区域的painter。

QPixmap puzzlePixmap(ui->widget->size());puzzlePixmap.fill(Qt::transparent);QPainter puzzlePainter(&puzzlePixmap);puzzlePainter.setRenderHints(QPainter::Antialiasing);puzzlePainter.setClipPath(cutoutpath);puzzlePainter.setPen(QPen(QColor(229, 228, 228), 2));puzzlePainter.drawPixmap(0, 0, ui->widget->width(), ui->widget->height(), pixmap);puzzlePainter.drawPath(cutoutpath);painter.drawPixmap(-m_offsetPoint.x() + m_value, 0, ui->widget->width(), ui->widget->height(), puzzlePixmap);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/42192.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

文心智能体平台快速创建一个HY(Lisp)编程小助手

现在可以在文心智能体平台&#xff0c;使用文心一言创建各种智能体了&#xff01;创建步骤如下&#xff1a; 创建知识库 可以使用本地上传的方式来提交&#xff0c;鼠标移动到”查看模板“&#xff0c;可以下载”知识库外链上传示例模版.xlsx“&#xff0c;按照模板里的格式&…

8.14 矢量图层面要素2.5D渲染

文章目录 前言2.5D渲染QGis设置面符号为2.5D二次开发代码实现2.5D 总结 前言 本章介绍矢量图层面要素2.5D渲染的使用说明&#xff1a;文章中的示例代码均来自开源项目qgis_cpp_api_apps 2.5D渲染 2.5D渲染可以将多边形渲染为类3D效果。 QGis设置面符号为2.5D 以"hou…

生成式AI的短板在于“Token”的存在

生成式AI模型处理文本的方式与人类不同。理解它们基于“token”的内部环境&#xff0c;可能有助于解释一些奇怪行为和固有局限性。 从小型设备上的Gemma到OpenAI领先行业的GPT-4o&#xff0c;大多数模型都是基于一种称为Transformer的架构。由于Transformer在将文本与其他类型…

[Multi-Modal] MDETR 论文及代码学习笔记

代码地址&#xff1a;https://github.com/ashkamath/mdetr 论文地址&#xff1a;https://arxiv.org/abs/2104.12763 多模态推理系统依靠预先训练的目标检测器从图像中提取感兴趣区域&#xff08;边界框包围区域&#xff09;。然而&#xff0c;这个关键模块通常被用作黑匣子&…

飞书 API 2-4:如何使用 API 将数据写入数据表

一、引入 上一篇创建好数据表之后&#xff0c;接下来就是写入数据和对数据的处理。 本文主要探讨数据的插入、更新和删除操作。所有的操作都是基于上一篇&#xff08;飞书 API 2-4&#xff09;创建的数据表进行操作。上面最终的数据表只有 2 个字段&#xff1a;序号和邮箱。序…

英语学习交流小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;每日打卡管理&#xff0c;备忘录管理&#xff0c;学习计划管理&#xff0c;学习资源管理&#xff0c;论坛交流 微信端账号功能包括&#xff1a;系统首页&#xff0c;学习资源&…

C++基础(八):类和对象 (下)

经过前面的学习&#xff0c;我们已经翻过了两座大山&#xff0c;类和对象入门知识就剩下这一讲了&#xff0c;加油吧&#xff0c;少年&#xff01; 目录 一、再谈构造函数 1.1 构造函数体赋值 1.2 初始化列表&#xff08;理解&#xff09; 1.3 explicit关键字&#xff08;C…

【Java探索之旅】继承概念_语法_父类的成员访问

文章目录 &#x1f4d1;前言一、继承1.1 继承的概念1.2 继承语法1.3 继承发生后 二、父类的访问2.1 父类成员变量访问2.2 父类成员方法访问 &#x1f324;️全篇总结 &#x1f4d1;前言 在面向对象编程中&#xff0c;继承是一种重要的概念&#xff0c;它允许我们创建一个类&…

html的作业

目录 作业题目 1.用户注册 A图 B代码 2.工商银行电子汇款单 A图 B代码 3.李白诗词 A图 B代码 4.豆瓣电影 A图 B代码 学习产出&#xff1a; 作业题目 1.用户注册 A图 B代码 <!DOCTYPE html> <html lang"zh"> <head><meta charset&qu…

Java技术栈总结:Redis篇

一、数据类型 Redis 自身是一个 Map&#xff0c;其中的所有数据均采用“key:value”的形式存储。 数据类型指的是存储的数据的类型&#xff0c;即 value 部分的类型&#xff0c;key 的部分只能是字符串。 value 部分的数据类型&#xff1a;<String、List、Hash、Set、Zse…

MSPM0G3507——编码器控制速度

绿色设置的为目标值100&#xff0c;红色为编码器实际数据 。 最后也是两者合在了一起&#xff0c;PID调试成功。 源码直接分享&#xff0c;用的是CCStheia&#xff0c;KEIL打不开。大家可以看一下源码的思路&#xff0c;PID部分几乎不用改 链接&#xff1a;https://pan.baid…

S32DS S32 Design Studio for S32 Platform 3.5 代码显示行号与空白符

介绍 NXP S32DS&#xff0c;全称 S32 Design Studio&#xff0c;s32 系列芯片默认使用 S32 Design Studio for S32 Platform 作为 IDE 集成开发环境&#xff0c;当前版本 S32 Design Studio for S32 Platform 3.5&#xff0c;IDE 可以简称 s32DS 使用 S32DS&#xff0c;可以认…

Qt 网络编程 网络信息获取操作

学习目标&#xff1a;网络信息获取操作 前置环境 运行环境:qt creator 4.12 学习内容 一、Qt 网络编程基础 Qt 直接提供了网络编程模块,包括基于 TCP/IP 的客户端和服务器相关类,如 QTcpSocket/QTcpServer 和 QUdpSocket,以及实现 HTTP、FTP 等协议的高级类,如 QNetworkRe…

【简单介绍下Memcached】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

昇思25天学习打卡营第08天 | 模型训练

昇思25天学习打卡营第08天 | 模型训练 文章目录 昇思25天学习打卡营第08天 | 模型训练超参数损失函数优化器优化过程 训练与评估总结打卡 模型训练一般遵循四个步骤&#xff1a; 构建数据集定义神经网络模型定义超参数、损失函数和优化器输入数据集进行训练和评估 构建数据集和…

uniapp 去掉小数末尾多余的0

文章目录 在uniapp或者一般的JavaScript环境中&#xff0c;要去掉小数末尾的0&#xff0c;可以使用以下几种方法&#xff1a; 使用parseFloat()函数 let num 123.4500; let result parseFloat(num); console.log(result); // 输出: 123.45字符串处理 将数字转换为字符串&am…

24年沈阳教师招聘报名全流程(电脑版)

公开招聘1876名事业编制工作人员 报名时间&#xff1a;7月8日10:00至7月11日16:00&#xff1b; 报名网站&#xff1a;&#xff1a;沈阳市考试院 报名流程&#xff1a; 1.报名 ①登录沈阳市考试院填写报名信息&#xff0c;上传照片 本人近期免冠2寸正面电子证jian照片&#xff0…

接口依赖-动态参数+数据依赖的代码

怎么写测试用例 接口名:被依赖的返回值的jsonpath表达式&#xff0c;有几个依赖往后写就可以 代码 如果caseinfo里的getisdep等于yes&#xff0c;并且&#xff0c;depkey不为空 用正则解析 在testrun里增加判断 判断的内容是正则表达式&#xff0c;先去匹配&#xff0c;再去…

2024年世界人工智能大会(WAIC)各大佬的精彩发言

2024年世界人工智能大会&#xff08;WAIC&#xff09;在上海举行&#xff0c;受到了广泛关注和参与。以下是大会首日的主要观点和议题的总结&#xff1a; AI 应用落地&#xff1a;大会讨论了AI应用如何落地&#xff0c;即如何在当前阶段利用大模型技术实现实际应用。 AI 安全&…

flask缓存、信号的使用

【 一 】flask-ache ​ 它为 Flask 应用程序提供了缓存支持。缓存是 Web 应用程序中非常常见的做法&#xff0c;用于存储频繁访问但不太可能经常更改的数据&#xff0c;以减少对数据库或其他慢速存储系统的访问&#xff0c;从而提高应用程序的性能和响应速度。 ​ Flask-Cach…