当前位置: 首页 > news >正文

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

目录

自定义recBox:

RecBoxItem类中添加动画效果:

两个添加TEXT和imgStyle的函数:

图片随机函数:

qqmusic.cpp:

recbox的初始化函数:

QT的一些额外加餐:

关于如何设置按钮的功能

connect函数

事件过滤器:实现监视目标对象事件 的作用

QPropertyAnimation的基本使用

QString

QJsonArray和QJsonObject

 

自定义recBox:

1. RecBox界⾯布局
① 新添加设计师界⾯,命名为RecBox。geometry的宽⾼修改为:685*440。
② 添加三个Widget,objectName依次修改为leftPage、musicContent、rightPage;
leftPage 和 rightPage的minimumSize和maximumSize修改宽为30,然后选中RecBox点击⽔平布
局。将RecBox的 margin和Spacing修改为0
③ 在upPage和downPage中各拖⼀个按钮,upPage中按钮objectName修改为btUp,minimumSize
的⾼度修改为 220;downPage中按钮objectName修改为btDown,minimumSize的⾼度修改为
220;然后选中upPage和 downPage点击⽔平布局。将upPagedownPage和的margin和
Spacing修改为0。
③ 在musicContent中拖两个Widget,objectName依次修改为recListUp和recListDown,然后选中
musicContent点 击垂直布局,将musicContent的margin和Spacing修改为0。(为了看清楚效果可
临时将recListUp背景⾊设置 为:background-color:green; 将recListDown背景⾊设置为:
background-color:red;)
④ 在recListUp和recListDown中分别拖两个⽔平布局器,依次命名为recListUpHLayout和
recListDownHLayout,选 中recListUp和recListDown点击⽔平布局,将margin和Spacing修改为0
做好美化后将QQMusic主界⾯中recPage⻚⾯中的recMusicBox和supplyMusicBox提升为RecBox


RecBoxItem类中添加动画效果:

重写eventfilter函数

bool RecBoxItem::eventFilter(QObject *watched, QEvent *event)
{if(watched == ui->musicImageBox){if(QEvent::Enter == event->type()){// 添加图片上移动画QPropertyAnimation* animation = new QPropertyAnimation(ui->musicImageBox, "geometry");animation->setDuration(150);animation->setStartValue(QRect(9,9, ui->musicImageBox->width(), ui->musicImageBox->height()));animation->setEndValue(QRect(9, 0, ui->musicImageBox->width(), ui->musicImageBox->height()));animation->start();connect(animation, &QPropertyAnimation::finished, this, [=](){delete animation;});}else if(QEvent::Leave == event->type()){// 添加图标下移动画QPropertyAnimation* animation = new QPropertyAnimation(ui->musicImageBox, "geometry");animation->setDuration(150);animation->setStartValue(QRect(9,0, ui->musicImageBox->width(), ui->musicImageBox->height()));animation->setEndValue(QRect(9, 9, ui->musicImageBox->width(), ui->musicImageBox->height()));animation->start();connect(animation, &QPropertyAnimation::finished, this, [=](){delete animation;});}return true;}return QObject::eventFilter(watched, event);
}

两个添加TEXT和imgStyle的函数:

void RecBoxItem::setText(const QString &text)
{ui->recBoxItemText->setText(text);
}void RecBoxItem::setImage(const QString &Imagepath)
{QString imgStyle="border-image:url("+Imagepath+");";ui->recMusicImage->setStyleSheet(imgStyle);
}

图片随机函数:

在qqmusic.cpp中定义图片随机选取并且存成嵌套qjsonobject的qjsonarray格式返回,后面会在qqmusic调用initrecitem函数,里面randompicture的返回值会作为参数。

QJsonArray QQMusic::RandomPicture()
{// 推荐⽂本 + 推荐图⽚路径QVector<QString> vecImageName;vecImageName<<"001.png"<<"003.png"<<"004.png"<<"005.png"<<"006.png"<<"007.png"<<"008.png"<<"009.png"<<"010.png"<<"011.png"<<"012.png"<<"013.png"<<"014.png"<<"015.png"<<"016.png"<<"017.png"<<"018.png"<<"019.png"<<"020.png"<<"021.png"<<"022.png"<<"023.png"<<"024.png"<<"025.png"<<"026.png"<<"027.png"<<"028.png"<<"029.png"<<"030.png"<<"031.png"<<"032.png"<<"033.png"<<"034.png"<<"035.png"<<"036.png"<<"037.png"<<"038.png"<<"039.png"<<"040.png";std::random_shuffle(vecImageName.begin(), vecImageName.end());// 001.png// path: ":/images/rec/"+vecImageName[i];// text: "推荐-001"QJsonArray objArray;for(int i = 0; i < vecImageName.size(); ++i){QJsonObject obj;obj.insert("path", ":/images/rec/"+vecImageName[i]);// arg(i, 3, 10, QCchar('0'))// i:要放⼊%1位置的数据// 3: 三位数// 10:表⽰⼗进制数// QChar('0'):数字不够三位,前⾯⽤字符'0'填充QString strText = QString("推荐-%1").arg(i, 3, 10, QChar('0'));obj.insert("text", strText);objArray.append(obj);}return objArray;}
recbox.h:#ifndef RECBOX_H
#define RECBOX_H#include <QWidget>
#include <QJsonArray>namespace Ui {
class RecBox;
}class RecBox : public QWidget
{Q_OBJECTpublic:explicit RecBox(QWidget *parent = nullptr);~RecBox();void initRecBoxUi(QJsonArray data, int row);//初始化推荐界面void createRecBoxItem();private:Ui::RecBox *ui;int row; // 记录当前RecBox实际总⾏数int col; // 记录当前RecBox实际每⾏有⼏个元素QJsonArray imageList; // 保存界⾯上的图⽚, ⾥⾯实际为key、value键值对};#endif // RECBOX_H

 

上面在recbox.h中定义了row和col作为行列

qqmusic.cpp:

    srand(time(NULL));ui->recMusicBox->initRecBoxUi(RandomPicture(),1);ui->supplyMusicBox->initRecBoxUi(RandomPicture(),2);

在recbox的构造函数里初始化行列数值

#include "ui_recbox.h"
#include<RecBoxItem.h>
#include <QJsonObject>RecBox::RecBox(QWidget *parent): QWidget(parent), ui(new Ui::RecBox),row(1),col(4)
{ui->setupUi(this);
}

recbox的初始化函数:

recbox.cppvoid RecBox::initRecBoxUi(QJsonArray data, int row)
{// 如果是两⾏,说明当前RecBox是主界⾯上的supplyMusicBoxif(2 == row){this->row = row;this->col = 8;}else{// 否则:只有⼀⾏,为主界⾯上recMusicBoxui->recListDown->hide();}// 图⽚保存起来imageList = data;// 往RecBox中添加图⽚createRecBoxItem();
}void RecBox::createRecBoxItem()
{// 创建RecBoxItem对象,往RecBox中添加// colfor(int i = 0; i < col; ++i){RecBoxItem* item = new RecBoxItem();// 设置⾳乐图⽚与对应⽂本QJsonObject obj = imageList[i].toObject();item->setText(obj.value("text").toString());item->setImage(obj.value("path").toString());// recMusicBox:col为4,元素添加到ui->recListUpHLayout中// supplyMuscBox: col为8, ui->recListUpHLayout添加4个,ui->recListDownHLayout添加4个// 即supplyMuscBox上下两⾏都要添加// 如果是recMusicBox:row为1,只能执⾏else,所有4个RecBoxItem都添加到ui->recListUpHLayout中// 如果是supplyMuscBox:row为2,col为8,col/2结果为4,i为0 1 2 3时,元素添加到ui->recListDownHLayout中// i为4 5 6 7时,元素添加到ui->recListUpHLayout中if(i >= col/2 && row == 2){ui->recListDownHLayout->addWidget(item);}else{ui->recListUpHLayout->addWidget(item);}}}

 

总结下来就是在recboxitem类里重写eventfilter函数设置动画,然后在recbox函数里添加图片/写初始化图片函数,在qqmusic类里写随机图片函数(输出json格式的array数组),在qqmusic类里调用初始化图片函数。

 

最后的效果:

 

QT的一些额外加餐:

 

关于如何设置按钮的功能

1.手动添加槽函数
2.定义类然后在相应的Widget位置提升为新的类
3.直接在cpp中实例化类然后添加ui
RecBoxItem* item = new RecBoxItem();
ui->recListUpHLayout->addWidget(item);
4.用connect函数连接
下面介绍connect函数

connect函数

信号槽机制,按钮是发送信号,窗口是接收信号,槽的本质就是对信号响应的函数,是一个回调函数

例1:

void QQMusic::connectSignalAndSlot()
{connect(ui->Rec, &BtForm::click, this, &QQMusic::onBtFormClick);connect(ui->music, &BtForm::click, this, &QQMusic::onBtFormClick);connect(ui->audio, &BtForm::click, this, &QQMusic::onBtFormClick);connect(ui->like, &BtForm::click, this, &QQMusic::onBtFormClick);connect(ui->local, &BtForm::click, this, &QQMusic::onBtFormClick);connect(ui->recent, &BtForm::click, this, &QQMusic::onBtFormClick);
}  

这里连接了6个`BtForm`类型按钮(`ui->Rec`, `ui->music`, `ui->audio`, `ui->like`, `ui->local`, `ui->recent`)的`click`信号到当前对象(`this`,即`QQMusic`实例)的同一个槽函数`onBtFormClick`。- 这意味着当这些按钮中的任何一个被点击时,都会触发`QQMusic::onBtFormClick`槽函数。

 

这里的第一个参数是目标对象界面中的按钮组件),第二个参数是触发信号自定义按钮类 BtForm 的点击信号),第三个参数接收者当前 QQMusic 类实例),第四个参数槽函数处理按钮点击的槽函数

 

例2:

connect(animation, &QPropertyAnimation::finished, this, [=](){delete animation;
});

这里连接了一个`QPropertyAnimation`对象(指针变量名为`animation`)的`finished`信号。- 当动画完成时,会触发一个Lambda表达式(作为槽函数)。- Lambda表达式以值捕获方式(`[=]`)捕获当前作用域的变量(注意:这里捕获的是`this`指针和`animation`指针,因为`animation`在外部定义)。- 在Lambda表达式内部,执行`delete animation;`,即删除动画对象,释放内存。

这里的第一个参数是针对musicImageBox创建的动画组件,第二个参数是结束触发信号,第三个参数是接收者this(recboxitem),第四个参数是槽函数(删除动画)

事件过滤器:实现监视目标对象事件 的作用

bool eventFilter(QObject *watched, QEvent *event);
 eventFilter 的第一个参数 obj 指向的是事件本应传递到的目标对象。
重写是类似这样的:
 bool Widget::eventFilter(QObject *obj, QEvent *event){if(obj == ui->label){//鼠标进入的时候if (event->type() == QEvent::Enter){ui->label->setText("我是红色");ui->label->setStyleSheet(redStyle);return true; //拦截事件,不再传递}else if(event->type() == QEvent::Leave) //鼠标离开{ui->label->setText("我是黑色");ui->label->setStyleSheet(blackStyle);return true;}return false;  //不拦截事件,允许继续传递,别的事件会传给label对象}// standard event processingreturn QWidget::eventFilter(obj, event);}

鼠标进入过滤->鼠标离开过滤

QPropertyAnimation的基本使用

常用接口函数

  • setTargetObject:设置仿真对象
  • setPropertyName:设置仿真属性的名称,
  • setDuration:设置仿真持续的时间
  • setStartValue:设置初始值
  • setEndValue:设置结束值
  • start:开始仿真
  • currentValue:返回当前值
  • setKeyValueAt:设置关键点的值
  • valueChanged:只要仿真追踪的值发生变化,就发送该信号

QString

QString 是 Qt 中的一个类,用于存储字符串,QString 没有父类。QString 存储的是一串字符,每个字符是一个 QChar 类型的数据。QChar 使用的是 UTF-16 编码,一个字符包含 2 字节数据。 对于超过 65535 的 Unicode 编码,QString 使用两个连续的 QChar 字符表示。UTF-16 是一种 Unicode 编码,能表示汉字,在 QString 字符串中一个汉字是一个字符。

 

QString 类定义了大量的接口函数用于字符串操作。QString在 Qt 类库中应用非常广泛,很多函数的参数是 QString 类型。

例如:

QString str = "Hello Qt";QString str1= "洋洋", str2= "得意"; 
QString str3= str1 + str2; //str3 ="洋洋得意" 
str1= str2 + str1; //str1 ="得意洋洋" QString str1= "卖", str2= "拐"; 
QString str3= str1; 
str1.append(str2); //str1 ="卖拐" 
str3.prepend(str2); //str3 ="拐卖" //等等还有好多函数

 

     

    RecBox添加RecBoxItem
    random_shuffle是打乱列表顺序的函数

     

    QJsonArray和QJsonObject

    这两个类都是用于处理JSON数据
    在Qt中,QJsonArray和QJsonObject是Qt JSON模块的一部分,用于表示JSON数据
    1. QJsonArray: - 功能:QJsonArray类用于封装一个JSON数组。 - 一个JSON数组是一个值的有序列表,这些值可以是不同的类型(包括字符串、数字、布尔值、对象、数组,以及null)。 - 在QJsonArray中,元素是通过索引(从0开始)来访问的。 - 常用操作: * 添加值:使用`append`、`push_back`或`insert`方法。 * 访问值:使用`at`方法或`operator[]`(注意:operator[]返回的是非const的引用,而at返回的是const引用)。 * 删除值:使用`removeAt`方法。 * 获取数组大小:使用`size`方法。 * 遍历:可以使用迭代器或简单的for循环(基于索引)。
    2. QJsonObject: - 功能:QJsonObject类用于封装一个JSON对象。 - 一个JSON对象是一个无序的键值对集合,其中键是字符串,值可以是各种JSON类型(包括数组、对象、基本类型等)。 - 在QJsonObject中,通过键(字符串)来访问对应的值。 - 常用操作: * 插入键值对:使用`insert`方法。 * 访问值:使用`value`方法或`operator[]`(注意:operator[]如果键不存在则会插入一个null值,而value方法不会修改对象)。 * 删除键值对:使用`remove`方法。 * 检查键是否存在:使用`contains`方法。 * 获取所有键:使用`keys`方法。 * 获取键值对数量:使用`size`方法。 * 遍历:可以使用迭代器或遍历键列表。
    QJsonArray:表示JSON数组,有序列表,通过索引访问。
    QJsonObject:表示JSON对象,键值对映射,通过键访问。
    例如:
    QJsonArray:QJsonArray arr;
    arr.append(42);          // 添加整数
    arr.append("Hello");     // 添加字符串
    arr.append(QJsonObject{ {"key", "value"} }); // 添加嵌套对象int num = arr[0].toInt();     // 获取索引 0 的值 → 42
    QString str = arr[1].toString(); // → "Hello"arr.replace(0, 100);     // 替换索引 0 的值
    arr.removeAt(1);         // 删除索引 1 的元素int size = arr.size();   // 获取元素数量
    bool isEmpty = arr.empty(); // 判空
    QJsonObject:QJsonObject obj;
    obj.insert("id", 1001);
    obj["name"] = "Alice";       // 使用运算符[]插入
    obj["scores"] = QJsonArray{90, 85, 95}; // 嵌套数组int id = obj["id"].toInt();          // → 1001
    QString name = obj.value("name").toString(); // → "Alice"obj["id"] = 2002;          // 修改值
    obj.remove("name");        // 删除键bool hasKey = obj.contains("scores"); // 检查键是否存在
    QStringList keys = obj.keys();      // 获取所有键 → ["id", "scores"]
    int size = obj.size();              // 键值对数量

     

     

     

    http://www.dtcms.com/a/303774.html

    相关文章:

  • 深入理解 Qt 元对象系统 (Meta-Object System)
  • WindowsAPI|每天了解几个winAPI接口之网络配置相关文档Iphlpapi.h详细分析六
  • [明道云]-基础教学2-工作表字段 vs 控件:选哪种?
  • HTTP 与 HTTPS 的区别
  • mapbox进阶,mapbox-gl-draw绘图插件扩展,编辑模式支持点、线、面的捕捉
  • Objective-c 初阶——异常处理(try-catch)
  • 盛最多水的容器-双指针
  • 注册发送手机短信
  • bash变量名不能有连字符
  • Spark初探:揭秘速度优势与生态融合实践
  • RabbitMQ面试精讲 Day 7:消息持久化与过期策略
  • H.264视频的RTP有效载荷格式(翻译自:RFC6184 第5节 RTP有效载荷格式)
  • 网络协议——MPLS(多协议标签转发)
  • 力扣30 天 Pandas 挑战(3)---数据操作
  • LeetCode 283 - 移动零
  • CTF-Web学习笔记:服务端请求伪造(SSRF)篇
  • 单片机学习笔记.PWM
  • 第4章唯一ID生成器——4.5 美团点评开源方案Leaf
  • 医疗AI新基建:MCP与A2A协议的破局与前瞻
  • JVM 崩溃(Fatal Error)解决方法
  • 影刀RPA_初级课程_玩转影刀自动化_EXCEL操作自动化
  • 《C++初阶之STL》【list容器:详解 + 实现】
  • JSON解析
  • Spring IOC 基于Cglib实现含构造函数的类实例化策略
  • 循环神经网络——动手学深度学习7
  • 板凳-------Mysql cookbook学习 (十二--------7)
  • SpringBoot 的@Repository 等注解的底层实现原理
  • 智能体安全与可信AI:防护机制与伦理考量
  • SpringBoot之起步依赖
  • 【使用python中列表注意事项】