QT项目-仿QQ音乐的音乐播放器(第二节)

目录

自定义控件:

BtForm类中实现

BtForm上的动画效果


自定义控件:

该控件实际由:图⽚、⽂字、动画三部分组成。图⽚和⽂字分别⽤QLabel展⽰,动画部分内部实际为4
个QLabel。
① 将BtForm的geometry的宽度和⾼度修改为200*35。
② 拖⼀个Widget到btForm中,objectName修改为btStyle,将btForm的margin和Spacing设置为0.
③ 拖2个QLable和1个Widget到btStyle中,并将objectName依次修改为btIcon、btText、lineBox
btIcon的minimumSize和maximumSize的宽度设置为30(为了看到效果可将颜⾊设置为red)
btText的minimumSize和maximumSize的宽度设置为90(为了看到效果可将颜⾊设置为green)
lineBox的minimumSize和maximumSize的宽度设置为30
然后选中btStyle,并将其margin和Spacing设置为0
④ 然后往lineBox内部拖4个QLabel,objectName依次修改为line1、line2、line3、line4,
minimumSize和 maximumSize的宽度均设置为2
一般调整格式的三板斧就是放widget或者label等各种元素,然后水平或者垂直布局,最后设置minimumSize和maximumSize的高宽,margin和Spacing设置为0。再者就是QSS样式表。
然后将bodyLeft内部onlineMusic和MyMusic中的QWidget全部提升为BtForm自定义类
然后变成这样的界面:

BtForm类中实现

设置按钮上的图片和文字信息,以及该按钮关联的page页面
BtForm.h:int id=0;BtForm.cpp:void BtForm::section(QString btIcon, QString content, int mid)
{ui->btIcon->setPixmap(QPixmap(btIcon));ui->btText->setText(content);this->id=mid;
}

然后在QQMusic的初始化函数里调用这里的section函数输入文本图片和id:

void BtForm::section(QString btIcon, QString content, int mid)
{ui->btIcon->setPixmap(QPixmap(btIcon));ui->btText->setText(content);this->id=mid;
}

博主在做的时候遇到了一个问题:

btform类在面板显示的时候没有hover和点击的背景色,后来经过调整,发现是被QLabel覆盖了,因此要在btsyle中提前设置让它下面的QLabel全部透明,然后在clearbg函数中也加上这一句,同理在mousePressEvent中也加上透明,然后还要在clearbg函数中将linebox设置透明放置鼠标放置在上面的时候背景不是灰色的。还有一个方法是将btsyle下所有控件的背景色都设置为透明。

最后效果是这样的:

BtForm上的动画效果

btform.hQPropertyAnimation *line1Animal;
QPropertyAnimation *line2Animal;
QPropertyAnimation *line3Animal;
QPropertyAnimation *line4Animal;btform.cppBtForm::BtForm(QWidget *parent): QWidget(parent), ui(new Ui::BtForm)
{ui->setupUi(this);// 设置line1的动画效果line1Animal = new QPropertyAnimation(ui->line1, "geometry", this);line1Animal->setDuration(1500);line1Animal->setKeyValueAt(0, QRect(0, 30, 2, 0));         // 起始位置下移line1Animal->setKeyValueAt(0.5, QRect(0, 15, 2, 15));       // 向上移动一点line1Animal->setKeyValueAt(1, QRect(0, 30, 2, 0));         // 回到起始位置line1Animal->setLoopCount(-1);line1Animal->start();// 设置line2的动画效果line2Animal = new QPropertyAnimation(ui->line2, "geometry", this);line2Animal->setDuration(1600);line2Animal->setKeyValueAt(0, QRect(7, 30, 2, 0));line2Animal->setKeyValueAt(0.5, QRect(7, 15, 2, 15));line2Animal->setKeyValueAt(1, QRect(7, 30, 2, 0));line2Animal->setLoopCount(-1);line2Animal->start();// 设置line3的动画效果line3Animal = new QPropertyAnimation(ui->line3, "geometry", this);line3Animal->setDuration(1700);line3Animal->setKeyValueAt(0, QRect(14, 30, 2, 0));line3Animal->setKeyValueAt(0.5, QRect(14, 15, 2, 15));line3Animal->setKeyValueAt(1, QRect(14, 30, 2, 0));line3Animal->setLoopCount(-1);line3Animal->start();// 设置line4的动画效果line4Animal = new QPropertyAnimation(ui->line4, "geometry", this);line4Animal->setDuration(1800);line4Animal->setKeyValueAt(0, QRect(21, 30, 2, 0));line4Animal->setKeyValueAt(0.5, QRect(21, 15, 2, 15));line4Animal->setKeyValueAt(1, QRect(21, 30, 2, 0));line4Animal->setLoopCount(-1);line4Animal->start();
}

这里QRect函数是:

  • QRect(int x, int y, int width, int height): 创建一个左上角坐标为(x, y),宽度为width,高度为height的矩形。

setKeyValueAt函数是:
        void setKeyValueAt(qreal step, const QVariant &value);
step:值再0~1之间,0表⽰开始,1表⽰停⽌
value:动画的⼀个关键帧,即动画现在的形态,假设是基于geometry,可以设置矩形的范围

经过调整效果如图:

void BtForm::clearBg()
{// 清除上⼀个按钮点击的背景效果,恢复之前的样式ui->btStyle->setStyleSheet("#btStyle:hover{ background:#D8D8D8;} QLabel{background-color : transparent;} #lineBox{background-color : transparent;}");ui->line1->hide();//隐藏动画ui->line2->hide();//隐藏动画ui->line3->hide();//隐藏动画ui->line4->hide();//隐藏动画
}void BtForm::showAnimal()
{ui->line1->show();ui->line2->show();ui->line3->show();ui->line4->show();
}void QQMusic::onBtFormClick(int id)
{// 1.获取当前⻚⾯所有btFrom按钮类型的对象QList<BtForm*> buttonList = this->findChildren<BtForm*>();// 2.遍历所有对象, 如果不是当前id的按钮,则把之前设置的背景颜⾊清除掉foreach (BtForm* btitem, buttonList){if (id != btitem->getId()){btitem->clearBg();}if (btitem->getId()==4){ui->local->showAnimal();//将local面板的linebox动画展示出来}}// 3.设置当前栈空间显⽰⻚⾯ui->stackedWidget->setCurrentIndex(id - 1);
\
}BtForm::BtForm(QWidget *parent): QWidget(parent), ui(new Ui::BtForm)
{ui->setupUi(this);ui->line1->hide();//隐藏动画ui->line2->hide();//隐藏动画ui->line3->hide();//隐藏动画ui->line4->hide();//隐藏动画// 设置line1的动画效果line1Animal = new QPropertyAnimation(ui->line1, "geometry", this);line1Animal->setDuration(1500);line1Animal->setKeyValueAt(0, QRect(0, 30, 2, 0));         // 起始位置下移line1Animal->setKeyValueAt(0.5, QRect(0, 15, 2, 15));       // 向上移动一点line1Animal->setKeyValueAt(1, QRect(0, 30, 2, 0));         // 回到起始位置line1Animal->setLoopCount(-1);line1Animal->start();// 设置line2的动画效果line2Animal = new QPropertyAnimation(ui->line2, "geometry", this);line2Animal->setDuration(1600);line2Animal->setKeyValueAt(0, QRect(7, 30, 2, 0));line2Animal->setKeyValueAt(0.5, QRect(7, 15, 2, 15));line2Animal->setKeyValueAt(1, QRect(7, 30, 2, 0));line2Animal->setLoopCount(-1);line2Animal->start();// 设置line3的动画效果line3Animal = new QPropertyAnimation(ui->line3, "geometry", this);line3Animal->setDuration(1700);line3Animal->setKeyValueAt(0, QRect(14, 30, 2, 0));line3Animal->setKeyValueAt(0.5, QRect(14, 15, 2, 15));line3Animal->setKeyValueAt(1, QRect(14, 30, 2, 0));line3Animal->setLoopCount(-1);line3Animal->start();// 设置line4的动画效果line4Animal = new QPropertyAnimation(ui->line4, "geometry", this);line4Animal->setDuration(1800);line4Animal->setKeyValueAt(0, QRect(21, 30, 2, 0));line4Animal->setKeyValueAt(0.5, QRect(21, 15, 2, 15));line4Animal->setKeyValueAt(1, QRect(21, 30, 2, 0));line4Animal->setLoopCount(-1);line4Animal->start();}

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

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

相关文章

【世纪龙科技】数字课程资源-新能源汽车概论

一、课程介绍本课程为通过项目任务式教学&#xff0c;全面系统的讲解了新能源汽车的基础知识及相关技能&#xff0c;培养和提高学生的动手能力和理论知识的工程应用能力。以典型工作任务带动知识与技能的学习&#xff0c;采用项目教学培养学生的岗位技能、学习能力和职业素养。…

iOS Core Data 本地数据库 使用详解:从模型关系到数据操作

一、引言&#xff1a;Core Data&#xff0c;在本地数据持久化中的地位在 iOS 开发中&#xff0c;本地数据存储几乎是每一个 App 都绕不开的问题。无论是缓存用户信息、离线浏览内容&#xff0c;还是记录用户操作历史&#xff0c;一个合适的数据持久化方案都能大大提升应用的体验…

Java-79 深入浅出 RPC Dubbo 动态路由架构详解:从规则设计到上线系统集成

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; AI炼丹日志-30-新发布【1T 万亿】参数量大模型&#xff01;Kim…

Linux内核中动态内存分配函数解析

在C语言中&#xff0c;动态内存分配通常用于在运行时申请内存。在内核编程中&#xff0c;动态内存分配与用户空间有所不同&#xff0c;因为内核需要更谨慎地处理内存&#xff0c;且不能使用用户空间的库&#xff08;如glibc&#xff09;。下面我们将详细分析Linux内核中动态申请…

Next.js 中配置不同页面布局方案

在 Next.js 应用中&#xff0c;你可以通过多种方式实现某些页面全屏、某些页面带菜单/页眉/页脚的需求。以下是几种实现方案&#xff1a; 方案一&#xff1a;使用多个布局组件 1. 创建不同的布局组件 // app/default-layout.tsx import Header from /components/header; import…

Spring Boot 使用外置 Servlet 容器:从配置到部署全指南

在 Spring Boot 开发中&#xff0c;我们通常使用嵌入式 Servlet 容器&#xff08;如 Tomcat&#xff09;&#xff0c;它能将应用打包成可执行 JAR&#xff0c;简化部署流程。但在某些场景下&#xff08;如需要支持 JSP、复杂的容器定制或企业级部署规范&#xff09;&#xff0c…

借助AI学习开源代码git0.7之九diff-files

借助AI学习开源代码git0.7之九diff-files diff-files.c 是一个用于比较工作目录中的文件和 Git 索引&#xff08;暂存区&#xff09;中文件的工具。 实质上&#xff0c;它是 git diff命令在不指定特定提交时功能的核心实现。 主要功能分析&#xff1a; 1. 核心功能 diff-files …

社区资源媒体管理系统设计与实现

社区资源媒体管理系统设计与实现 1. 系统概述 社区资源媒体管理系统是一个专为社区户外广告打造的高效、专业化平台&#xff0c;旨在实现社区媒体的数字化管理、智能投放和便捷交易。该系统将整合社区各类广告资源&#xff0c;为广告主、物业公司和社区居民提供一站式服务。 1.…

12.1.6 weak_ptr

weak_ptr weak_ptr会指向一个share_ptr&#xff08;使用一个share_ptr来初始化weak_ptr&#xff09;&#xff0c;但并不会增加这个share_ptr的引用计数器&#xff0c;其析构也不会减少share_ptr的引用计数器。 构造函数及使用 #include <iostream> #include <memory&g…

深度分析Java内存模型

Java 内存模型&#xff08;Java Memory Model, JMM&#xff09;是 Java 并发编程的核心基石&#xff0c;它定义了多线程环境下线程如何与主内存&#xff08;Main Memory&#xff09;以及线程的本地内存&#xff08;工作内存&#xff0c;Working Memory&#xff09;交互的规则。…

代码随想录算法训练营第五十二天|图论part3

101. 孤岛的总面积 题目链接&#xff1a;101. 孤岛的总面积 文章讲解&#xff1a;代码随想录 思路&#xff1a; 与岛屿面积差不多&#xff0c;区别是再dfs的时候&#xff0c;如果碰到越界的&#xff0c;需要用一个符号标记这不是孤岛再continue #include <iostream> #i…

前端实现 excel 数据导出,封装方法支持一次导出多个Sheet

一、前言 后台管理项目有时会有需要前端导出excel表格的功能&#xff0c;有时还需要导出多个sheet&#xff0c;并给每个sheet重新命名&#xff0c;下面我们就来实现一下。 二、实现效果图 三、实现步骤 1、 安装 命令行安装 xlsx 和 file-saver npm install xlsx -S npm i…

【Lambda 表达式】返回值为什么是auto

一个例子&#xff1a; int x 10; auto add_x [x](int y) -> int {return x y; }; int result add_x(5); // 结果是 15lambda 是匿名类型&#xff0c;必须用 auto 来接收。&#xff08;必须写auto&#xff0c;不可省略&#xff09;内层 -> auto 是函数的返回类型自动推…

【小董谈前端】【样式】 CSS与样式库:从实现工具到设计思维的跨越

CSS与样式库&#xff1a;从实现工具到设计思维的跨越 一、CSS的本质&#xff1a;样式实现的「施工队」 CSS作为网页样式的描述语言&#xff0c;其核心能力在于&#xff1a; 精确控制元素的尺寸、位置、颜色实现响应式布局和动画效果与HTML/JavaScript协同完成交互体验 但CS…

MTSC2025参会感悟:大模型 + CV 重构全终端 UI 检测技术体系

目录 一、传统 UI 自动化的困局:高成本与低效率的双重枷锁 1.1 根深蒂固的技术痛点 1.2 多维度质量挑战的叠加 二、Page eyes 1.0:纯视觉方案破解 UI 检测困局 2.1 纯视觉检测的核心理念 2.2 页面加载完成的智能判断 2.3 视觉模型驱动的异常检测 2.4 大模型赋能未知异…

使用Claude Code从零到一打造一个现代化的GitHub Star项目管理器

在日常的开发工作中&#xff0c;我们经常会在GitHub上star一些有用的项目库。随着时间的推移&#xff0c;star的项目越来越多&#xff0c;如何有效管理这些项目成为了一个痛点。 今天&#xff0c;分享我使用Claude Code从零构建的一个GitHub Star管理插件。项目背景与需求分析 …

为什么 Linux 启动后还能升级内核?

✅ 为什么 Linux 启动后还能升级内核&#xff1f; 简单结论&#xff1a; 因为 “安装/升级内核 ≠ 当前就使用该内核”&#xff0c;Linux允许你安装多个内核版本&#xff0c;并在下次启动时选择其中一个来加载运行。 &#x1f9e0; 举个现实生活类比 你在穿一件衣服&#xff08…

Go语言实战案例-统计文件中每个字母出现频率

以下是《Go语言100个实战案例》中的 文件与IO操作篇 - 案例19&#xff1a;统计文件中每个字母出现频率 的完整内容。本案例适合用来练习文件读取、字符处理、map统计等基础技能。&#x1f3af; 案例目标读取一个本地文本文件&#xff0c;统计并打印出其中每个英文字母&#xff…

Notepad++工具操作技巧

1、notepad -> ctrlf -> 替换(正则表达式) -> $-a ->每行的行尾加a&#xff1b; 2、notepad -> ctrlf -> 替换(正则表达式) -> ^-a ->每行的行首加a &#xff1b; 3、按住alt切换为列模式 4、删除空行-不包括有空格符号的空行 查找替代 查找目标…

领码课堂 | Java与AI的“硬核“交响曲:当企业级工程思维遇上智能时代

摘要 &#x1f680; 在AI工业化落地的深水区&#xff0c;Java正以其独特的工程化优势成为中流砥柱。本文系统解构Java在AI项目全生命周期中的技术矩阵&#xff0c;通过"三阶性能优化模型"、"微服务化AI部署架构"等原创方法论&#xff0c;结合大模型部署、M…