《二十二》Qt 音频编程实战---做一个音频播放器

1.UI界面制作

        作为一个音乐播放器,最基础的肯定就是播放、暂停、上一首以及下一首,为了使这个界面好看一点,还加入了音量控制、进度条、歌曲列表等内容,至于这种配色和效果好不好看,我也不知道,个人审美一如既往的不达标。

QT设计界面有两种方式,一种是直接通过纯代码的方式实现,将各种控件以及布局通过代码的方式编排成一个完整的UI界面,但是这种方式较为麻烦也比较复杂,代码量也比较大,还有一种就是通过UI文件拖拽QT控件,来对整个布局进行排版的效果,我这里为了省事采用的就是这种方式,至于实际效果怎么样那就要看个人审美了。

整个UI界面内部使用到的基础控件有以下几种:

控件名称       

控件类控件功能
PushButtonQPushButton 用来控制添加、删除、清空歌曲列表的功能
horizontalSliderQSlider用来控制播放进度、音量等功能
listWidgetQListWidget歌单列表,内部存入添加的歌曲
groupBox  QgroupBox内部放入播放列表
label Qlabel  标签,可以用来显示提示信息以及图片

2.加入播放器类

UI界面设计完成之后就是加入播放器类。QT中使用播放器类需要加入对应的链接模块,通过查询QT的帮助手册可以查到,然后在项目的pro文件中加上即可。

加入链接模块后,需要添加我们需要使用到的一些相关的播放器类头文件 

#include<QMediaPlayer>
#include<QMediaPlaylist>
#include<QFileDialog>

3.播放器初始化

首先在头文件先定义出我们所需要的成员以及槽函数,定义一个QMediaPlayer类以及QMediaPlaylist类,还需要记录歌曲时长,以及位置,方便我们拖动进度条。

QMediaPlaylist类,可以为QMediaPlayer提供一个播放列表,它其实是QMediaContent对象的列表,QMediaPlayer通过函数setPlaylist来设置一个播放列表。QMediaPlaylist通过函数addMedia向播放列表添加一个媒体文件。QMediaplaylist类的播放模式:PlaybackMode

private:Ui::MainWindow *ui;QMediaPlayer *player;QMediaPlaylist *playlist;QString drtTime;//歌曲时长QString pstTime;//播放位置private slots:void Onstatechg(QMediaPlayer::State state);//按钮切换状态void Onplaylishchg(int pos);//播放列表void OnDrtchg(qint64 drt);//歌曲总时间长度void Onpstchg(qint64 pos);//播放歌曲当前位置

对于槽函数Onstatechg()的实现,我们对state状态进行比较,从而对按钮:播放,暂停,停止按钮进行处理。

void MainWindow::Onstatechg(QMediaPlayer::State state)//按钮切换状态
{ui->pushButton_player->setEnabled(!(state==QMediaPlayer::PlayingState));ui->pushButton_puse->setEnabled(state==QMediaPlayer::PlayingState);ui->pushButton_stop->setEnabled(state==QMediaPlayer::PlayingState);
}
槽函数Onplaylishchg() 的实现,获取listWidget中的项目,来显示到下方歌曲名称的label中
void MainWindow::Onplaylishchg(int pos)//播放列表
{ui->listWidget->setCurrentRow(pos);QListWidgetItem *item=ui->listWidget->currentItem();if(item){ui->label_name->setText(item->text());}
}

槽函数OnDrtchg()的实现,先获取进度条的最大长度,根据获取的歌曲时间,转化成分,秒。放到歌曲时间label中

void MainWindow::OnDrtchg(qint64 drt)//歌曲总时间长度
{ui->horizontalSlider_speed->setMaximum(drt);int sec=drt/1000;//总共多少秒int min=sec/60;//分sec=sec%60;//秒drtTime=QString::asprintf("%d:%d",min,sec);ui->label_time->setText(pstTime+"/"+drtTime);
}

调整进度条,Onpstchg() 与上面方法类似,目的就是更新位置

void MainWindow::Onpstchg(qint64 pos)//播放歌曲当前位置,更新变化
{if(ui->horizontalSlider_speed->isSliderDown()){return;}ui->horizontalSlider_speed->setSliderPosition(pos);int sec=pos/1000;int min=sec/60;sec=sec%60;pstTime=QString::asprintf("%d:%d",min,sec);ui->label_time->setText(pstTime+"/"+drtTime);
}

接着就是槽函数链接了:

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);player=new QMediaPlayer(this);playlist=new QMediaPlaylist(this);playlist->setPlaybackMode(QMediaPlaylist::Loop);//循环模式player->setPlaylist(playlist);connect(player,SIGNAL(stateChanged(QMediaPlayer::State)),this,SLOT(Onstatechg(QMediaPlayer::State)));connect(player,SIGNAL(positionChanged(qint64)),this,SLOT(Onpstchg(qint64 )));connect(player,SIGNAL(durationChanged(qint64)),this,SLOT(OnDrtchg(qint64 )));connect(playlist,SIGNAL(currentIndexChanged(int)),this,SLOT(Onplaylishchg(int)));
}

4.功能控件

再接着我们来实现各种按钮以及拖动进度条事件的槽函数:

这些都是我们要实现的槽函数:

先从打开文件开始:

void MainWindow::on_pushButton_open_clicked()
{//添加歌曲QString currentpath=QDir::homePath();//当前位置QString dlgtitle="请选择音频文件:";//文件对话框标题QString strfilter="所有文件(*.*);;音频文件(*.mp3);;mp3文件(*.mp3)";//文件过滤器QStringList filelist=QFileDialog::getOpenFileNames(this,dlgtitle,currentpath,strfilter);if(filelist.count()<1){return;}for(int i=0;i<filelist.count();i++){QString afile=filelist.at(i);playlist->addMedia(QUrl::fromLocalFile(afile));//添加文件QFileInfo fileinfo(afile);ui->listWidget->addItem(fileinfo.fileName());//将文件添加到界面listwidget控件}if(player->state()!=QMediaPlayer::PlayingState){playlist->setCurrentIndex(0);}player->play();
}

首先要获取到位置,通过文件过滤来找到我们所需要的mp3文件,根据选中的文件数量依次添加到listWidget中,

剩下的 就比较简单了,我们全放出来:

void MainWindow::on_pushButton_player_clicked()
{if(playlist->currentIndex()<0){playlist->setCurrentIndex(0);}player->play();
}void MainWindow::on_pushButton_puse_clicked()
{player->pause();
}void MainWindow::on_pushButton_stop_clicked()
{player->stop();
}void MainWindow::on_pushButton_prev_clicked()
{playlist->previous();
}void MainWindow::on_pushButton_next_clicked()
{playlist->next();
}void MainWindow::on_pushButton_volumn_clicked()
{bool mutex=player->isMuted();player->setMuted(!mutex);if(mutex){ui->pushButton_volumn->setIcon(QIcon(":/icon/sound.png"));}else{ui->pushButton_volumn->setIcon(QIcon(":/icon/mute.png"));}
}void MainWindow::on_horizontalSlider_Volumn_valueChanged(int value)
{player->setVolume(value);
}void MainWindow::on_horizontalSlider_speed_valueChanged(int value)
{player->setPosition(value);
}

以及图标我们可以创建一个资源文件,来放图标:

后续在ui文件中导入:

 

5. 总结

        到这里基本是一个简单的音乐播放器就基本实现了,虽然里面有很多功能写的不是很详细,也有一部分操作我没有做,但是基本能实现播放、暂停、切换等基本功能。

        如果后期需要对播放器的功能进行添加可以自行添加,比方说,QT有自带的视频播放功能,可以将中间的GIF图片换成播放歌曲的MV,还可以添加一个comboBox控件来选择当前播放器的播放模式,QT有内置的宏可以直接设置,我这里是直接选择的循环播放。

        还有就是好像可以实现从网络获取歌曲的方法,这种的话就可以不用提前下载好歌曲了,大家可以自己去找一下,不要问我为什么没做这种,问就是我是菜鸡,我不会。

        好了,差不多到这里也要结束了,作为一个QT的初学者,里面有很多设置方法在各位大佬看来可能很笨,但是目前就只有这种水平了,而且大家如果对各种基础控件的样式不满意,可以去自己找一下各种样式表,自己设置一下,我这里就没有做太多这种操作了。

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

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

相关文章

智启未来:富唯智能AI-ICDP引领的可重构柔性装配产线

在全球制造业竞争日益激烈的今天&#xff0c;如何快速响应市场变化、提高生产效率、降低生产成本&#xff0c;成为了企业面临的重要挑战。随着产品个性化时代的到来&#xff0c;装配产品频繁变换&#xff0c;多品种小批量的生产模式逐渐成为主流。在这一背景下&#xff0c;富唯…

Coredns搭建DNS服务

CoreDNS 是一个灵活、可扩展的 DNS 服务器&#xff0c;常用于 Kubernetes 环境中&#xff0c;但也可以在其他场合单独部署。以下是在 Ubuntu 系统上部署 CoreDNS 的基本步骤&#xff1a; 步骤 1: 安装 CoreDNS Ubuntu 官方仓库可能不包含最新版本的 CoreDNS&#xff0c;所以我…

c#---枚举与结构体

一、枚举 枚举是一组命名整型常量。 枚举类型是使用 enum 关键字声明的。 C# 枚举是值类型。 这里假如我们要做个切水果的游戏&#xff1a; //1.定义水果类型 public enum FruitType {Apple,Lemon,Watermelon,Banana,Cherry,COUNT//水果总数 }// 2.随机刷新水果 public stat…

Linux 系统启动时设置一个全局环境变量

在 Linux 系统中&#xff0c;如果你想要在启动时设置一个全局环境变量&#xff0c;你可以将其写入某些特定的启动文件中。这些文件在用户登录时被读取&#xff0c;从而设定环境变量。以下是一些方法&#xff1a; 方法 1: /etc/environment 在 /etc/environment 中设置的变量对…

【QT教程】QT6 Debug技巧 QT调试

QT6 Debug技巧 使用AI技术辅助生成 QT界面美化视频课程 QT性能优化视频课程 QT原理与源码分析视频课程 QT QML C扩展开发视频课程 免费QT视频课程 您可以看免费1000个QT技术视频 免费QT视频课程 QT统计图和QT数据可视化视频免费看 免费QT视频课程 QT性能优化视频免费看 免费Q…

python 前台页面和oracle数据库联动案例-用户注册

今天是python 入门day3&#xff0c;案例实现界面如图&#xff0c;比较简单&#xff0c; 一个简单的用户注册页面&#xff0c;并且可以与Oracle数据库进行交互。 界面如图&#xff1a; 实现这个简单demo的过程中&#xff0c;遇到很多错误&#xff0c; 1、提交过程中提示主键不…

照片文件夹惊变白板?揭秘背后的原因及恢复秘籍

我们生活在一个数字化时代&#xff0c;照片已经成为记录生活的重要方式。然而&#xff0c;当你兴冲冲地打开保存珍贵记忆的文件夹时&#xff0c;却发现里面的照片全都变成了白板&#xff0c;这种心情无异于晴天霹雳。那么&#xff0c;这究竟是怎么回事呢&#xff1f; 照片文件夹…

【记录】常见的前端设计系统(Design System)

解释一下设计系统的定义&#xff0c;以及在国内&#xff0c;都有那些优秀的设计系统可以学习&#xff0c;希望可以帮到大家。 什么是设计系统&#xff08;Design System)&#xff1f; 设计系统&#xff08;Design System&#xff09;是一套综合性的指导原则、组件和规则&…

react router v6总结

一、使用createBrowserRouter()创建路由&#xff1a; 1、src/router/index.js&#xff1a; import { createBrowserRouter } from "react-router-dom"; import ErrorPage from "/pages/404/";const router createBrowserRouter([{path: "/",e…

Mysql8.0.30一次表锁问题的解决

起因 给material_config_field_data表的字段建立全文索引的时&#xff0c;发现该表卡死&#xff0c;然后无法对该表进行任何操作。 查找问题 执行sql #这个命令会显示InnoDB存储引擎的详细状态信息&#xff0c;包括锁等待和锁争用的信息 SHOW ENGINE INNODB STATUS结果 复制S…

stable diffusion教程

Stable Diffusion 是一种流行的图像生成模型&#xff0c;它可以根据文本提示生成高质量的图片。如果你想了解如何使用 Stable Diffusion&#xff0c;这里有一些基本的步骤和资源&#xff0c;可以帮助你开始使用&#xff1a; ### 1. 安装 Stable Diffusion 首先&#xff0c;你需…

语言基础 /CC++ 可变参函数设计与实践,变参函数的实现、使用、替代方法

文章目录 概述适用于做可变参数的数据类型格式化字符串输出用int做变长参数类型用结构体指针做变长参数类型用double做变长参数类型用结构体直接做变长参数类型 变参函数与宏定义符号 ... 不能透传符号 ... 不接受ap做参数_VA_ARGS_ 代表可变参数 回调可变参数函数取代变参函数…

Linux 第二十四章

&#x1f436;博主主页&#xff1a;ᰔᩚ. 一怀明月ꦿ ❤️‍&#x1f525;专栏系列&#xff1a;线性代数&#xff0c;C初学者入门训练&#xff0c;题解C&#xff0c;C的使用文章&#xff0c;「初学」C&#xff0c;linux &#x1f525;座右铭&#xff1a;“不要等到什么都没有了…

Spring MVC(二)

1. 注解RequestMapping修饰类 在Spring MVC中一般都是使用注解RequestMapping来映射请求&#xff0c;也就是通过它来指定控制器可以处理哪些URL请求&#xff0c;相当于Servlet中在web.xml中配置的映射地址作用一致。在上一节的内容中&#xff0c;我们通过注解RequestMapping改进…

计算机系统基础知识

计算机软件基础知识计算机软件基础知识 软件构件 构件又称为组件&#xff0c;是一个自包容、可复用的程序集&#xff0c;这个集合整体向外提供统一的访问接口&#xff0c; 构件外部只能通过接口来访问构件&#xff0c;而不能直接操作构件的内部。 构件的两个最重要的特性是自…

vue3.0(五) reactive全家桶

文章目录 1 reactive1.1 reactive的应用1.2 reactive的特点1.3 reactive的注意1.4 reactive的局限性 2 toRefs3 isReactive4 shallowReactive5 readonly5.1 readonly 详细信息5.2 readonly函数创建一个只读的响应式对象5.3 如何修改嵌套在只读响应式对象中的对象? 6 isReadonl…

小程序(三)

十三、自定义组件 &#xff08;二&#xff09;数据方法声明位置 在js文件中 A、数据声明位置&#xff1a;data中 B、方法声明位置methods中&#xff0c;这点和普通页面不同&#xff01; Component({/*** 组件的属性列表*/properties: {},/*** 组件的初始数据*/data: {isCh…

在RK3588开发板使用FFMpeg 结合云服务器加SRS实现摄像头数据推流到云端拱其他设备查看

今天测试了一把在开发板把摄像头数据推流到云端服务器&#xff0c;然后给其他电脑通过val软件拉取显示摄像头画面&#xff0c;浅浅记录一下大概步骤 1.开发板端先下载ffmpeg apt install ffmpeg2.云服务器先安装SRS的库 云服务器我使用ubuntu系统&#xff0c;SRS是个什么东西&…

优雅处理Python 使用xlrd 读取 Excel 报错:xlrd.compdoc.CompDocError

在用python xlrd库读取excel时&#xff0c;有时候会遇到 xlrd.compdoc.CompDocError报错。 其实注释掉库种raise的那几行&#xff0c;可以是可以&#xff0c;但是要修改库文件&#xff0c;并不好。 最好的方式是&#xff1a; wb open_workbook(fpath, formatting_infoTrue…

Mujoco210 和 Mujoco-py 在 Ubuntu22.04 下的安装

mujoco和mujoco-py的关系:mujoco是一个物理引擎,主要应用于强化学习和最优化控制领域。mujoco-py是mujoco编程的 Python 接口,由OpenAI Gym开发,可以使用mujoco_py方便地调用mujoco的API。 mujoco官网: https://mujoco.org/ 1.安装 Mujoco210 1. 从 Github下载 Mujoco …