QT 简易音乐播放器

news2025/2/26 7:16:39

目录

放置控件

获取mp3文件

播放音乐

准备工作

加载模块

加载头文件

new一个output对象,Mediaplayer对象

    把outpout对象交给mediaplayer对象    

给播放器设置音乐

播放

优化

上一曲下一曲功能

 双击歌曲播放

获取音乐时长和音乐播放时间

让音乐进度条跟随音乐走

调节音乐进度条更改音乐进度

音量调节

喇叭静音

音量进度条


放置控件

获取mp3文件

首先我们需要点击文件夹按钮的时候弹出一个新界面.因此我们需要QFileDialog类,这个函数就是新增一个界面.然后我们需要调QFileDialog下的getExistingDirectory函数,也就是打开一个已经存在的文件夹.

getExistingDirectory函数的第一个参数是父节点,第二个参数是标题,第三个参数是文件夹路径.返回值是QString:

我们需要把这个字符串转为一个路径,我们可以将其强转为QDir类型,然后再通过entryList函数将该路径下目录里的mp3文件全部过滤出来.代入如下:

void MainWindow::on_explorer_clicked()
{
    // 弹出文件对话框,让用户选择音乐文件夹,默认路径为"D://QTproject//music//assert//Music"
    QString path = QFileDialog::getExistingDirectory(this, "请选择音乐", "D://QTproject//music//assert//Music");

    // 创建QDir对象,用于操作指定的目录
    QDir dir(path);

    // 获取目录下所有以".mp3"结尾的文件,存入QStringList对象
    QStringList musicList = dir.entryList(QStringList()<<"*.mp3");

    // 打印音乐列表,用于调试
    qInfo()<<musicList;

    // 将获取到的音乐文件列表添加到UI的listWidget组件中
    ui->listWidget->addItems(musicList);
}

接下来我们需要把获取到的mp3文件展示出来,我们在主界面上放置一个listWidget控件.然后向listWidget里添加我们将才获取到的mp3文件:

  ui->listWidget->addItems(musicList);

我们拉一个横向滑块作为音乐进度条,一个纵向滑块作为音量调节条:

播放音乐

准备工作

加载模块

QT       += core gui multimedia

加载头文件

#include<QMediaPlayer>  //播放器
#include<QAudioOutput>  //输出

new一个output对象,Mediaplayer对象

    //先new一个output对象
    auto audioOutput=new QAudioOutput(this);  //把内存交给当前窗口管理(即关闭当前窗口就析构)
    //再new一个Mediaplayer对象
    auto mediaplayer=new QMediaPlayer(this);

    把outpout对象交给mediaplayer对象    

    mediaplayer->setAudioOutput(audioOutput);

给播放器设置音乐

mediaplayer->setSource(QUrl::fromLocalFile("D:/QTproject/music/assert/Music/来一碗老于 - 解药 (Single Version).mp3"));

播放

mediaplayer->play();

现在选中文件之后就会自动播放mediaplayer指向的setSource里路径下的音乐.

但是我们的需求是通过我们的音乐播放按钮播放我们listwidget上选中的音乐.

优化

我们首先让光标默认选择默认选中第一首歌(即选中第一行)

ui->listWidget->setCurrentRow(0);

然后我们把音乐完整路径保存到qlist里

    
    QList<QUrl> playlist;  //全局变量,定义于.h文件

    for(auto file:musicList)
    {
        playlist.append(QUrl::fromLocalFile(path+"/"+file));
    }

经过上面的步骤,所有的歌都存到playlist里面了

现在我们就可以通过播放按钮来播放音乐了(点击播放键调用playlist里和光标选中行一样下标的音乐)

//播放音乐按钮
void MainWindow::on_btn_play_clicked()
{
   //播放当前选中的音乐

     //获取选择的行
     int index=ui->listWidget->currentRow();
     //播放对应下标的音乐
     mediaplayer->setSource(playlist[index]);
     mediaplayer->play();
}

此时我们通过点击播放按钮可以达到播放音乐的效果,但是不能停止音乐.因此我们需要一个标志位,来标识当前是什么状态:

void MainWindow::on_btn_play_clicked()
{
    switch(mediaplayer->playbackState())  //播放器当前的播放状态
    {

        case QMediaPlayer::PlaybackState::PlayingState:  //播放状态
        {
            //正在播放音乐就暂停音乐
            mediaplayer->pause();
            break;
        }

        case QMediaPlayer::PlaybackState::PausedState:  //暂停状态
        {
         //暂停状态就播放音乐
            mediaplayer->play();
            break;
        }

        case QMediaPlayer::PlaybackState::StoppedState:  //停止状态
        {
            //停止状态就播放音乐
                //播放当前选中的音乐
                //获取选择的行
                int index=ui->listWidget->currentRow();
                //播放对应下标的音乐
                mediaplayer->setSource(playlist[index]);
                mediaplayer->play();
                break;
        }
    }
}

现在我们就可以自由控制播放暂停音乐了.

上一曲下一曲功能

上一曲

上一曲就是让listWidget选择上一行,然后playlist下标--

void MainWindow::on_btn_left_clicked()
{

    CurIndexPlay--;
    if(CurIndexPlay<0)CurIndexPlay=playlist.size()-1;  //防止下标越界
    ui->listWidget->setCurrentRow(CurIndexPlay);
    mediaplayer->setSource(playlist[CurIndexPlay]);
    mediaplayer->play();
}

下一曲

下一曲就是让ListWidget选择下一行,然后playlist下标++

void MainWindow::on_btn_right_clicked()
{
    //下一曲就是让Listwidget选择下一行
    //mediaplay下标++
    CurIndexPlay=(CurIndexPlay+1)%playlist.size();  //为了防止下标越界
    ui->listWidget->setCurrentRow(CurIndexPlay);
    mediaplayer->setSource(playlist[CurIndexPlay]);
    mediaplayer->play();
}

 双击歌曲播放

我们重写listwidget的双击槽函数  void on_listWidget_doubleClicked(const QModelIndex &index);

void MainWindow::on_listWidget_doubleClicked(const QModelIndex &index)
{
    CurIndexPlay=index.row();
    mediaplayer->setSource(playlist[CurIndexPlay]);
    mediaplayer->play();
}

这样我们就可以双击歌曲直接播放了

获取音乐时长和音乐播放时间

获取当前音乐播放时长必须通过信号与槽来获取

现在就可以显示当前正在播放的音乐的进度时间和音乐总时长

让音乐进度条跟随音乐走

现在我们让进度条跟随音乐进度:

现在进度条就可以跟着音乐走了:"

调节音乐进度条更改音乐进度


    connect(ui->playCourseSlider,&QSlider::sliderMoved,mediaplayer,&QMediaPlayer::setPosition);

音量调节

可以看到ui中有一个喇叭,旁边有一个进度条,我们实现拖动进度条改变音量,而直接点击喇叭则静音,再次点击喇叭开音.
1.进度条右键,选择valueChange()槽函数,注意不要选两个参数的。

喇叭静音

//拖动音量进度条改变声音
void MainWindow::on_Sound_heigorlow_valueChanged(int value)
{
    audioOutput->setVolume(value);
}

音量进度条

已经有一个名为audioOutputQAudioOutput对象,以及一个名为btn_sound的按钮。

首先,您需要在MainWindow类中添加一个成员变量来跟踪当前的静音状态:

// MainWindow类的私有部分
QAudioOutput *audioOutput; // 假设您已经有一个QAudioOutput对象
bool isMuted = false; // 用于跟踪是否静音

// 在构造函数或初始化代码中连接按钮信号
connect(ui->btn_sound, &QPushButton::clicked, this, &MainWindow::toggleMute);

然后,实现toggleMute槽函数:

void MainWindow::toggleMute()
{
    // 切换静音状态
    isMuted = !isMuted;

    // 设置音量以反映新的静音状态
    if (isMuted) {
        // 如果是静音状态,则设置音量为0
        audioOutput->setVolume(0.0);
    } else {
        // 如果不是静音状态,则设置音量为1(或者您希望的非静音音量)
        audioOutput->setVolume(1.0);
    }
}

因为我们不想让音量条一开始就显示出来,又因为qslide没有visible属性.所以我们只能在MainWindow的构造函数或初始化函数中设置滑块为隐藏状态

ui->Sound_heigorlow->setVisible(false);

这样,音量条初始时就不会显示出来了:

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

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

相关文章

解决element-ui回车键绑定按钮功能后却刷新浏览器的问题

最近写代码时&#xff0c;遇到要给回车键绑定确定的功能&#xff0c;并且打开对话框时要自动获取输入框焦点&#xff0c;发现一但重新打开浏览器&#xff0c;第一次执行回车键的功能时就会刷新浏览器&#xff0c;后续则会成功执行。但是一但再一次重新打开浏览器&#xff0c;还…

【简历】北京某985大学:JAVA秋招简历指导,面试通过率较高

注&#xff1a;为保证用户信息安全&#xff0c;姓名和学校等信息已经进行同层次变更&#xff0c;内容部分细节也进行了部分隐藏 简历说明 我们今天要看一位来自25届985同学的JAVA简历。 既然要参加校招的话&#xff0c;我们校招法典的第一准则&#xff1a;定你的学校层次。 …

win11中vsstudio2019使用winusb开usb应用

根据微软官方文档&#xff0c;在安装使用winusb之前&#xff0c;需求wdk环境。 下载 Windows 驱动程序工具包 (WDK) - Windows drivers | Microsoft Learn WDK环境安装 访问安装官网Previous WDK versions and other downloads - Windows drivers | Microsoft Learn 点开vs…

鸿蒙「TaskPool|Worker」多线程并发使用详解,这一篇足够!

概念介绍 鸿蒙的多线程并发TaskPool和Worker&#xff0c;他们具有相同内存模型&#xff0c;线程间隔离内存不共享。在项目中若使用到&#xff0c;有几个较重要的条件或特点这里简单作出列举。 CPU密集型任务&#xff0c;说白了是计算型耗时任务&#xff1b; I/O密集型任务&…

C# 静态方法和实例方法

一、静态成员&#xff0c;实例成员&#xff0c;静态方法&#xff0c;实例方法 静态成员就是用static修饰的字段&#xff1b; 实例成员就是没有被static修饰的字段&#xff1b; 静态方法就是用static修饰的方法&#xff1b; 实例方法就是没有被static修饰的方法&#xff1b;…

OriginPro快速上手指南:数据可视化与分析的利器

目录 OriginLab - Origin and OriginPro - Data Analysis and Graphing Softwarehttps://www.originlab.com/​编辑 一、安装与界面概览 安装 界面概览 二、基础操作 数据输入 创建图表 三、高级功能 数据分析 自动化与脚本 Origin 提供了几个小工具 四、技巧与提示…

AI编程-vscode安装“通义灵码”

“通义灵码”是一款基于阿里云通义代码大模型打造的智能编码助手 1、vscode中&#xff0c;选择插件&#xff0c;输入“tongyi” &#xff0c;弹出插件选项 2、点击install 安装 3、弹出登录提示 4、选择log in&#xff0c;弹出阿里云登录界面 登录成功后提示 5、返回vscode…

【吸引力法则】人生欲:追求深度体验与宇宙链接

文章目录 探究人生欲&#xff1a;追求深度体验与宇宙链接唤醒人生欲&#xff1a;克服配得感的三大障碍法执的压制家庭的继承 探究人生欲&#xff1a;追求深度体验与宇宙链接 在人生的广阔舞台上&#xff0c;我们时常探寻着那些能够引领我们走向更深层次成长与体验的力量。今天&…

C语言—函数递归

一、递归概念 递归其实是⼀种解决问题的⽅法&#xff0c;在C语⾔中&#xff0c;递归就是函数⾃⼰调⽤⾃⼰。下面举一个例子&#xff1a; 上述就是⼀个简单的递归程序&#xff0c;只不过上⾯的递归只是为了演⽰递归的基本形式&#xff0c;不是为了解决问题&#xff0c;代码最终…

ddos造成服务器瘫痪后怎么办

在服务器遭受DDoS攻击后&#xff0c;应立即采取相应措施&#xff0c;包括加强服务器安全、使用CDN和DDoS防御服务来减轻攻击的影响。rak小编为您整理发布ddos造成服务器瘫痪后怎么办。 当DDoS攻击发生时&#xff0c;首先要做的是清理恶意流量。可以通过云服务提供商提供的防护措…

java解析facebook的android app直投下的Referral URL

背景&#xff1a; 在facebook的应用推广中&#xff0c;一般使用两种方式&#xff0c;一种是app直投&#xff0c;一种是w2a。 app直投就是用户点击广告直接跳转到应用商店进行下载应用 w2a就是通过落地页方式引导用户进行应用下载 在w2a模式下&#xff0c;可以通过落地页链接…

Repeat方法:取模运算教材与Unity控制台输出数值不同的原因

学习该知识点的参考教材&#xff1a;Unity API解析/陈宏泉编著.——北京&#xff1a;人民邮电出版社&#xff0c;2014.9 编辑脚本的环境&#xff1a;Visual Studio 2022 在学习该本教材的第五章Mathf类的内容&#xff0c;通过跟随教材上的代码了解不同UnityAPI的具体用法时&a…

【数据结构】七、查找:1.查找的概念、线性结构查找(顺序、折半(二分)、插值、稠密、分块、倒排)

一、查找Search 文章目录 一、查找Search1.查找的基本概念1.1基本概念1.2算法评价标准 二、线性结构1.顺序表查找❗1.1顺序查找1.1.1算法思想1.1.2顺序查找效率分析 2.有序表查找❗2.1折半查找2.1.1算法思想2.1.2判定树构造2.1.3通过判定树进行查找效率分析2.1.4被查找概率不相…

ReactNative笔记(自用)

环境 ios更换gem镜像源&#xff1a; 查看当前源: gem sources -l 移除默认源: gem sources --remove https://rubygems.org/。添加新的源: 添加 Ruby China 的镜像源&#xff1a; gem source -a https://gems.ruby-china.com/或者添加其他镜像源。 清华大学的gem源: htt…

进阶-1.存储引擎

存储引擎 存储引擎1.MySQL体系结构2.存储引擎简介3.存储引擎特点3.1 InnoDB3.2 MyISAM3.3 Memory 4. 存储引擎选择 存储引擎 1.MySQL体系结构 2.存储引擎简介 存储引擎就是存储数据、建立索引、更新/查询数据等技术的实现。存储引擎是基于表的&#xff0c;而不是基于库的&…

【数学分析笔记】第2章第1节实数系的连续性(1)

2. 数列极限 2.1 实数系的连续性 人类对数系认识的历史&#xff1a; 人类最早对数系的认识是自然数集合 N \mathbb{N} N&#xff0c;自然数系对加法和乘法是封闭的&#xff08;这里的封闭是指&#xff1a;若 m ∈ N , n ∈ N ⇒ m n ∈ N , m n ∈ N m\in\mathbb{N},n\in\ma…

芯片用什么胶粘接牢固?​​​​​​​

芯片用什么胶粘接牢固?芯片粘接胶的牢固性对于电子产品的性能和可靠性至关重要。选择合适的胶水可以确保芯片能够稳定、可靠地固定在基板上。芯片的粘接通常涉及几种不同类型的胶水&#xff0c;每种胶水都有其特定的应用场景和性能特点。以下是几种常见的用于芯片粘接的胶水类…

C Primer Plus第十二章编程练习

第十二章编程练习 第一题要求我们不使用全局变量&#xff0c;修改程序12.4&#xff0c;那我们就用指针作为参数去传递变量的地址&#xff0c;去修改变量的值&#xff0c;完整程序代码以及运行结果如下&#xff1a; #include<stdio.h> //int units 0; void critic(int …

node卸载与安装

1.直接使用卸载程序卸载 2.安装新的Node 官网下载并执行下一步直到完成 3.Idea配置不同版本的node file->settings->Languages & Frameworks->Node.js and NPM->增加带选项->选择指定版本

ubuntu下使用docker、socket、yolov5进行图像处理数据交互记录

ubuntu下使用docker、socket、yolov5进行图像处理数据交互记录 概述&#xff1a;主要实现了在宿主机上通过8000端口传递一张图像给docker镜像&#xff0c;然后镜像中处理后&#xff0c;通过8001端口回传处理后的图像给宿主机。 第一章、构建镜像 一、dockerfile文件 1.拉取…