《QT实用小工具·四十五》可以在界面上游泳的小鱼

1、概述
源码放在文章末尾

该项目实现了灵动的小鱼,可以在界面上跟随鼠标点击自由的游泳,项目demo演示如下所示:
在这里插入图片描述

项目部分代码如下所示:

#include "magicfish.h"
#include <QtMath>
#include <QPainter>
#include <QPainterPath>
#include <QVariantAnimation>MagicFish::MagicFish(QQuickPaintedItem *parent): QQuickPaintedItem(parent),m_fishRadius(30),m_finLen(30 * 1.3),m_bodyHeight(30 * 3.2),m_headAlpha(200),m_bodyAlpha(225),M_finAlpha(120),m_mainAngle(0.0),m_curValue(0),m_wave(1.0),m_startFin(false),m_paintPoint(false)
{m_animation = new QVariantAnimation(this);m_animation->setDuration(180 * 1000);m_animation->setStartValue(0);m_animation->setEndValue(54000);m_animation->setLoopCount(-1);connect(m_animation, &QVariantAnimation::valueChanged, this, [this](const QVariant &value){m_curValue = value.toInt();update();});connect(this, &QQuickItem::widthChanged, this, &MagicFish::resize);connect(this, &QQuickItem::heightChanged, this, &MagicFish::resize);m_animation->start();
}void MagicFish::paint(QPainter *painter)
{painter->setRenderHint(QPainter::Antialiasing);QPointF middle_pos = QPointF(width() / 2, height() / 2);m_headPos = calcPoint(middle_pos, m_bodyHeight / 2.0, m_mainAngle);paintMyPoint(painter, m_headPos);paintMyPoint(painter, middle_pos);painter->setPen(Qt::NoPen);painter->setBrush(QBrush(QColor(20, 203, 232, 50)));painter->setBrush(QBrush(QColor(244, 92, 71, m_headAlpha)));painter->drawEllipse(m_headPos, m_fishRadius, m_fishRadius);qreal angle = m_mainAngle + qSin(qDegreesToRadians(m_curValue * 1.2 * m_wave)) * 2;QPointF end_pos = calcPoint(m_headPos, m_bodyHeight, angle - 180);QPointF pos1 = calcPoint(m_headPos, m_fishRadius, angle - 80);QPointF pos2 = calcPoint(end_pos, m_fishRadius * 0.7, angle - 90);QPointF pos3 = calcPoint(end_pos, m_fishRadius * 0.7, angle + 90);QPointF pos4 = calcPoint(m_headPos, m_fishRadius, angle + 80);QPointF central_left = calcPoint(m_headPos, m_bodyHeight * 0.56, angle - 130);QPointF central_right = calcPoint(m_headPos, m_bodyHeight * 0.56, angle + 130);QPainterPath path;path.moveTo(pos1);path.quadTo(central_left, pos2);path.lineTo(pos3);path.quadTo(central_right, pos4);path.lineTo(pos1);painter->setBrush(QBrush(QColor(244, 92, 71, m_bodyAlpha)));painter->drawPath(path);paintMyBody(painter, end_pos, m_fishRadius * 0.7, 0.6, angle);QPointF left_fin_pos = calcPoint(m_headPos, m_fishRadius * 0.9, angle + 110);paintMyFishFins(painter, left_fin_pos, true, angle);QPointF right_fin_pos = calcPoint(m_headPos, m_fishRadius * 0.9, angle - 110);paintMyFishFins(painter, right_fin_pos, false, angle);
}void MagicFish::resize()
{m_fishRadius = qMin(width(), height()) / 10.0;m_finLen = m_fishRadius * 1.3;m_bodyHeight = m_fishRadius * 3.2;
}QPointF MagicFish::calcPoint(const QPointF &pos, qreal length, qreal angle)
{qreal delta_x = qCos(qDegreesToRadians(angle)) * length;qreal delta_y = qSin(qDegreesToRadians(angle - 180)) * length;return QPointF(pos + QPointF(delta_x, delta_y));
}void MagicFish::paintMyPoint(QPainter *painter, const QPointF pos)
{if(m_paintPoint){painter->save();painter->setPen(QPen(Qt::black, 3));painter->setBrush(QBrush(Qt::black));painter->drawPoint(pos);painter->restore();}
}void MagicFish::paintMyFishFins(QPainter *painter, const QPointF &pos, bool is_left, qreal father_angle)
{qreal contral_angle = 115;qreal fin_angle = m_startFin ? qSin(qDegreesToRadians(m_curValue * 16.1 * m_wave)) * 12.0 : 2;QPainterPath path;path.moveTo(pos);QPointF end_pos = calcPoint(pos, m_finLen, is_left ? father_angle + fin_angle + 180 :father_angle - fin_angle - 180);QPointF control_pos = calcPoint(pos, m_finLen * 1.8, is_left ?father_angle + contral_angle + fin_angle :father_angle - contral_angle - fin_angle);path.quadTo(control_pos, end_pos);path.lineTo(pos);painter->save();painter->setBrush(QBrush(QColor(244, 92, 71, M_finAlpha)));painter->drawPath(path);painter->restore();
}void MagicFish::paintMyBody(QPainter *painter, const QPointF &pos, qreal seg_r, qreal MP, qreal father_angle)
{qreal angle = father_angle + qCos(qDegreesToRadians(m_curValue * 1.5 * m_wave)) * 15;qreal length = seg_r * (MP + 1);QPointF end_pos = calcPoint(pos, length, angle - 180);QPointF pos1 = calcPoint(pos, seg_r, angle - 90);QPointF pos2 = calcPoint(end_pos, seg_r * MP, angle - 90);QPointF pos3 = calcPoint(end_pos, seg_r * MP, angle + 90);QPointF pos4 = calcPoint(pos, seg_r, angle + 90);painter->save();painter->setBrush(QBrush(QColor(244, 92, 71, m_headAlpha)));painter->drawEllipse(pos, seg_r, seg_r);painter->drawEllipse(end_pos, seg_r * MP, seg_r * MP);QPainterPath path;path.moveTo(pos1);path.lineTo(pos2);path.lineTo(pos3);path.lineTo(pos4);painter->drawPath(path);painter->restore();paintMyBody2(painter, end_pos, seg_r * 0.6, 0.4, angle);
}void MagicFish::paintMyBody2(QPainter *painter, const QPointF &pos, qreal seg_r, qreal MP, qreal father_angle)
{qreal angle = father_angle + qSin(qDegreesToRadians(m_curValue * 1.5 * m_wave)) * 35;qreal length = seg_r * (MP + 2.7);QPointF end_pos = calcPoint(pos, length, angle - 180);QPointF pos1 = calcPoint(pos, seg_r, angle - 90);QPointF pos2 = calcPoint(end_pos, seg_r * MP, angle - 90);QPointF pos3 = calcPoint(end_pos, seg_r * MP, angle + 90);QPointF pos4 = calcPoint(pos, seg_r, angle + 90);paintMyTail(painter, pos, length, seg_r, angle);painter->save();painter->setBrush(QBrush(QColor(244, 92, 71, m_headAlpha)));painter->drawEllipse(end_pos, seg_r * MP, seg_r * MP);QPainterPath path;path.moveTo(pos1);path.lineTo(pos2);path.lineTo(pos3);path.lineTo(pos4);painter->drawPath(path);painter->restore();
}void MagicFish::paintMyTail(QPainter *painter, const QPointF &pos, qreal length, qreal max_w, qreal angle)
{qreal w = qAbs(qSin(qDegreesToRadians(m_curValue * 1.7 * m_wave)) * max_w + m_fishRadius / 5.0 * 3.0);QPointF end_point1 = calcPoint(pos, length, angle - 180);QPointF end_point2 = calcPoint(pos, length - 10, angle - 180);QPointF pos1 = calcPoint(end_point1, w, angle - 90);QPointF pos2 = calcPoint(end_point1, w, angle + 90);QPointF pos3 = calcPoint(end_point2, w - m_fishRadius / 1.5, angle - 90);QPointF pos4 = calcPoint(end_point2, w - m_fishRadius / 1.5, angle + 90);QPainterPath path;path.moveTo(pos);path.lineTo(pos3);path.lineTo(pos4);path.lineTo(pos);painter->save();painter->setBrush(QBrush(QColor(244, 92, 71,     m_headAlpha)));painter->drawPath(path);path.closeSubpath();path.moveTo(pos);path.lineTo(pos1);path.lineTo(pos2);path.lineTo(pos);painter->drawPath(path);painter->restore();
}void MagicFish::setWave(qreal value)
{m_wave = value;
}qreal MagicFish::getFishR() const
{return m_fishRadius;
}qreal MagicFish::getAngle()
{return m_mainAngle;
}QRectF MagicFish::geometry() const
{return QRectF(x(), y(), width(), height());
}QPointF MagicFish::getHeadPos() const
{return m_headPos;
}void MagicFish::setCurrentAngle(qreal angle)
{m_mainAngle = angle;update();
}void MagicFish::setFinAnimation(bool start)
{m_startFin = start;
}void MagicFish::setFishR(int value)
{m_fishRadius = value;m_finLen = value * 1.3;m_bodyHeight = value * 3.2;update();
}

源码下载

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

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

相关文章

C++:map和set的封装

关于红黑树的模拟实现&#xff0c;大家不清楚的先去看看博主的博客再来看这篇文章&#xff0c;因为set和map的封装底层都是利用用的红黑树。所以这里不会过多介绍红黑树的相关内容&#xff0c;而更多的是去为了契合STL中的红黑树去进行改造&#xff0c;让封装的set和map能够去复…

CMake使用

一、CMake 是什么 CMake 是一个跨平台的自动化构建系统&#xff0c;它使用配置文件 CMakeLists.txt 来管理软件构建过程。CMake 基于 Makefile 做了二次开发。 二、单个文件目录 # CMake 最低版本号要求 cmake_minimum_required(VERSION 3.16.3)# 工程名 project(CMakeSingle)…

uniapp自定义返回事件(封装)

uniapp自定义返回事件 在我们使用uniapp时&#xff0c;我们导航栏一般都是自定义的&#xff0c;比如用uview框架的导航栏&#xff0c;那么返回事件通常会遇到以下几个问题 返回事件前需要做一些额外的处理 h5项目刷新页面后返回失效 返回按钮点击后到指定页面 如果只是监听返…

PhotosCollage for Mac:优雅且实用的照片拼贴软件

PhotosCollage for Mac是一款优雅且实用的照片拼贴软件&#xff0c;为Mac用户提供了一个便捷、高效的平台&#xff0c;以创建精美、个性化的照片拼贴作品。 PhotosCollage for Mac v1.4.1激活版下载 该软件界面简洁直观&#xff0c;操作便捷。用户只需将想要拼贴的照片拖入“照…

CSS基础:position定位的5个类型详解!

你好&#xff0c;我是云桃桃。 一个希望帮助更多朋友快速入门 WEB 前端的程序媛。 云桃桃-大专生&#xff0c;一枚程序媛&#xff0c;感谢关注。回复 “前端基础题”&#xff0c;可免费获得前端基础 100 题汇总&#xff0c;回复 “前端工具”&#xff0c;可获取 Web 开发工具合…

Andorid复习

组件 TextView 阴影 android:shadowColor"color/red" 阴影颜色android:shadowRadius"3.0" 阴影模糊度&#xff08;大小&#xff09;android:shadowDx"10.0" 横向偏移android:shadowDy"10.0" 跑马灯 这里用自定义控件 public cla…

日本极致产品力 | 源自内蒙古,日本99.7%的人都喝过都百年畅销饮料

​《极致产品力》日本深度研学是一个顾问式课程,可以帮助企业找产品、找方向、找方法,在日本终端市场考察中洞悉热销产品背后的成功逻辑,了解最新最前沿的产品趋势和机会。结合日本消费趋势中国转化的众多经验,从品牌、包装、卖点、技术和生产工艺等多方面寻找中国市场的解决方…

WIFI/BT中蓝牙的硬件资源是如何调度的 UART和PCM接口传输的是什么信号

安卓或IOS手机中&#xff0c;wifi/bt中的蓝牙是如何调度硬件资源的&#xff0c;尤其是UART和PCM是如何分配的。M.2 wifi/bt模块或其他形式的模块中&#xff0c;蓝牙是如何调度硬件资源的&#xff0c;尤其是UART和PCM是如何分配的。今天我们就图文并茂的解决这个问题。 蓝牙文件…

新买的设备自带的仪器校准证书,是否可以作为校准报告使用?

设备在刚刚购买时&#xff0c;有些商家会承诺&#xff0c;在交付设备的同时&#xff0c;还会交付设备的校准证书&#xff0c;这证书是附赠的&#xff0c;属于商家给客户的一种福利&#xff0c;面对附赠的仪器校准证书&#xff0c;很多客户也会有疑惑&#xff0c;这附赠的证书有…

UTONMOS:用区块链技术拓展商业边界在哪里?

引言 大约从 2021 年Web 3 这个新概念开始受到风险基金和科技圈的普遍关注。但如果你对过去几年区块链的发展历史足够了解&#xff0c;就应该已经意识到现在的 Web 3 并不是什么新技术&#xff0c;甚至不是旧技术的进步&#xff0c;它只是一个基于区块链技术的宏大构想。 我是…

Unity 如何制作和发布你的 Package

一、制作你的第一个 Package Unity Package 不做过多赘述&#xff0c;像 URP 本质上也是一个 Package&#xff0c;在 Unity 中可以通过菜单栏 → Window → Package manager 来管理你当前的所有 Package 本篇文章主要介绍&#xff1a;如何制作并发布属于你的 Package 1.1 Pac…

自制贪吃蛇小游戏

此片文章涉及到到控制台设置的相关操作&#xff0c;虚拟键码&#xff0c;宽字符输出等&#xff0c;有些地方大家可能会看不懂&#xff0c;可以阅读以下文章来进一步了解&#xff1a; 控制台程序设置-CSDN博客 效果展示&#xff1a; QQ2024428-181932 源码已放在文章结尾 目录 …

Graph Neural Networks(GNN)学习笔记

本学习笔记的组织结构是&#xff0c;先跟李沐老师学一下&#xff0c;再去kaggle上寻摸一下有没有类似的练习&#xff0c;浅做一下&#xff0c;作为一个了解。 ———————————0428更新—————————————— 课程和博客看到后面准备主要看两个&#xff1a;GCN和…

ubuntu安装Anaconda安装及conda使用

一. 安装anaconda3详细教程 1、下载镜像 清华大学开源软件镜像站下载地址&#xff1a; https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ 下拉到最低端选择Linux&#xff0c;选择最新版&#xff08;32/64位&#xff09;下载。这里我下载的是版本Anaconda3-4.3.30-Linux…

Java中的File类

File类概述和构造方法 File&#xff1a;它是文件和目录路径名的抽象表示 文件和目录是可以通过File封装成对象的 对于File而言&#xff0c;其封装的并不是一个真正存在的文件&#xff0c;仅仅是一个路径名而已&#xff0c;它可以存在&#xff0c;也可以不存在 我们对Fie的操…

大厂常见算法50题-替换空格

专栏持续更新50道算法题&#xff0c;都是大厂高频算法题&#xff0c;建议关注, 一起巧‘背’算法! 文章目录 题目解法一 String类replace方法解法二 遍历替换总结 题目 解法一 String类replace方法 String类自带的replace&#xff0c;方法传入两个char类型的参数&#xff0c;分…

【MySQL 数据宝典】【索引原理】- 004 优化示例-join in exist

一、join 优化原理 1.1 基本连接方式介绍 JOIN 是 MySQL 用来进行联表操作的&#xff0c;用来匹配两个表的数据&#xff0c;筛选并合并出符合我们要求的结果集。 1.2 驱动表的定义 1.2.1 什么是驱动表 多表关联查询时,第一个被处理的表就是驱动表,使用驱动表去关联其他表.驱…

使用 SSH 密钥配置 Git 账号需要以下步骤

1、生成 SSH 密钥&#xff1a; 如果你还没有 SSH 密钥&#xff0c;可以使用以下命令在电脑终端中生成一个新的 SSH 密钥&#xff1a; ssh-keygen -t rsa -b 4096 -f /Users/XXXX/.ssh/id_rsa_my_personal -C "your_emailexample.com" ssh-keygen 是用于生成 SSH 密…

《Fundamentals of Power Electronics》——Buck、Boost、Buck-Boost三个电路的CCM-DCM工作特性总结

Buck、Boost、Buck-Boost这三个电路的CCM-DCM工作特性总结如下表所示&#xff1a; Buck、Boost、Buck-Boost这三个电路工作在DCM模式下电压传输比的对比图如下所示&#xff1a; 由上图可知&#xff0c;Buck-Boost电路的工作特性是一条斜率为的直线&#xff0c;Buck电路和Boost电…

RK3588 - RKNN(Rockchip 神经处理单元)的逆向工程

本文翻译自https://jas-hacks.blogspot.com/2024/02/rk3588-reverse-engineering-rknn.html RK3588 NPU 的内部操作和功能主要隐藏在名为RKNPU2的闭源 SDK 中。由于对大型语言模型 (LLM) 的兴趣以及对transform模型最佳矩阵乘法的追求&#xff0c;想了解 RKNPU SDK 新引入的矩阵…