#QT(本地音乐播放器)

1.IDE:QTCreator


2.实验:之前做的音乐播放器只做了一个界面,是因为跟的课程发现到后面需要付费,并且WINGW6.2.0运行QMediaPlayer时无法运行,会崩溃,现在退一步用WINGW5.12.2做一个本地音乐播放器


3.记录:

(1)鼠标悬停,背景颜色改变

(2)listwidget以及水平滑块

(3)双击播放音乐的实现

void Widget::on_listWidget_doubleClicked(const QModelIndex &index)    //双击播放指定音乐
{
    mediaplayer->setMedia(playlist[index.row()]);
    mediaplayer->play();
}

(4)打开文件夹的实现

void Widget::on_openfile_pb_clicked()   //打开文件按钮按下
{
    //QMessageBox::information(this,"文件","打开文件");
    //打开对话框,让用户选择音乐的存放路径
    auto path=QFileDialog::getExistingDirectory(this,"选择音乐所在的路径","c:/Users/***/Desktop/music_path");   //打开指定文件夹***涉及个人信息
//    qInfo()<<path;   //打印刚才打开文件夹
    QDir dir(path);    //
    auto musiclist=dir.entryList(QStringList()<<"*.mp3"<<"*.wav");  //筛出mp3和wav文件
//  qInfo()<<musiclist;  //打印帅选后的音乐
    //把筛选出的文件在listwidget显示出来
    ui->listWidget->addItems(musiclist);
    //默认选择第一首音乐
    ui->listWidget->setCurrentRow(0);
    //把音乐完整路径保存起来
    for(auto file : musiclist)
        playlist.append(QUrl::fromLocalFile(path+"/"+file));  //append附加
//    qInfo()<<playlist;   //将附加的音乐列表打印出来
}

 (5)播放的实现

void Widget::on_playorpause_pb_clicked()    //播放或者暂停按下
{
    if(mediaplayer->state()!=QMediaPlayer::PlayingState)  //不处于播放状态
    {
        //得到音乐索引
        int index=ui->listWidget->currentRow();
        //设置音乐路径
        mediaplayer->setMedia(playlist[index]);
    }
    //判断当前状态
    switch(mediaplayer->state())
    {
     case QMediaPlayer::StoppedState:mediaplayer->play();break;
     case QMediaPlayer::PausedState:mediaplayer->play();break;  //停止则播放
     case QMediaPlayer::PlayingState:mediaplayer->pause();break;  //正在播放则暂停
 //    default:mediaplayer->play();break;
    }
}

(6)上一首,下一首的实现

void Widget::on_lastsong_pb_clicked()      //上一首
{
    int index=ui->listWidget->currentRow();
    if(index==0)    //如果在第一行
        ui->listWidget->setCurrentRow(ui->listWidget->count()-1);
    else
        ui->listWidget->setCurrentRow(index-1);

    mediaplayer->setMedia(playlist[ui->listWidget->currentRow()]);
    mediaplayer->play();
}


void Widget::on_next_song_pb_clicked()    //下一首
{
    int index=ui->listWidget->currentRow();
    if(index == (ui->listWidget->count()-1))  //如果在最后一首歌
        ui->listWidget->setCurrentRow(0);
    else
        ui->listWidget->setCurrentRow(index+1);

    mediaplayer->setMedia(playlist[ui->listWidget->currentRow()]);
    mediaplayer->play();
}

 (7)获取音乐总时长,当前播放进度,改变当前播放进度,改变音量的实现

    //获取当前文件总播放时间
    connect(mediaplayer,&QMediaPlayer::durationChanged,this,[=](qint64 duration)
    {
        ui->total_playtime->setText(QString("%1:%2").arg(duration/1000/60,2,10,QChar('0')).arg(duration/1000%60,2,10,QChar('0')));//2为位宽,10为进制,QChar('0')为填充0
        ui->play_slider->setRange(0,duration);
    });
    //根据进度改变当前播放时间
    connect(mediaplayer,&QMediaPlayer::positionChanged,this,[=](qint64 position)
    {
        ui->now_playtime->setText(QString("%1:%2").arg(position/1000/60,2,10,QChar('0')).arg(position/1000%60,2,10,QChar('0')));//2为位宽,10为进制,QChar('0')为填充0
        ui->play_slider->setValue(position);
    });
    //拖动滑块,让音乐进度随滑块改变而改变
    connect(ui->play_slider,&QSlider::sliderMoved,mediaplayer,&QMediaPlayer::setPosition);
    //拖动滑块,改变音量
    connect(ui->volume_slider,&QSlider::sliderMoved,mediaplayer,&QMediaPlayer::setVolume);

(8)总体运行效果

 

MyMusic 2024-03-08 10-02-19


4.代码

pro

QT       += core gui multimedia widgets

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++17

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    widget.cpp

HEADERS += \
    widget.h

FORMS += \
    widget.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

RESOURCES += \
    resource.qrc

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPaintEvent>
#include <QMediaPlayer>
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    void paintEvent(QPaintEvent *);
private slots:
    void on_openfile_pb_clicked();

    void on_playorpause_pb_clicked();

    void on_lastsong_pb_clicked();

    void on_next_song_pb_clicked();

    void on_listWidget_doubleClicked(const QModelIndex &index);


    void on_close_pb_clicked();

    void on_about_pb_clicked();

private:
    Ui::Widget *ui;
    QMediaPlayer *mediaplayer;
    QList<QUrl> playlist;     //播放列表
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QPainter>
#include <QMessageBox>   //消息提示
#include <QFileDialog>  //操作文件
#include <QDir>         //操作路径
#include <QDebug>
//#include <QString>
#include <QMediaPlayer>
#include <QAudioOutput>  //音乐输出

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    this->setFixedSize(this->geometry().size());       //设置固定大小
    this->setWindowFlag(Qt::FramelessWindowHint);      //关闭窗口标题

    //定义一个媒体播放对象
    mediaplayer = new QMediaPlayer(this);
    //设置音量
    mediaplayer->setVolume(50);
    //获取当前文件总播放时间
    connect(mediaplayer,&QMediaPlayer::durationChanged,this,[=](qint64 duration)
    {
        ui->total_playtime->setText(QString("%1:%2").arg(duration/1000/60,2,10,QChar('0')).arg(duration/1000%60,2,10,QChar('0')));//2为位宽,10为进制,QChar('0')为填充0
        ui->play_slider->setRange(0,duration);
    });
    //根据进度改变当前播放时间
    connect(mediaplayer,&QMediaPlayer::positionChanged,this,[=](qint64 position)
    {
        ui->now_playtime->setText(QString("%1:%2").arg(position/1000/60,2,10,QChar('0')).arg(position/1000%60,2,10,QChar('0')));//2为位宽,10为进制,QChar('0')为填充0
        ui->play_slider->setValue(position);
    });
    //拖动滑块,让音乐进度随滑块改变而改变
    connect(ui->play_slider,&QSlider::sliderMoved,mediaplayer,&QMediaPlayer::setPosition);
    //拖动滑块,改变音量
    connect(ui->volume_slider,&QSlider::sliderMoved,mediaplayer,&QMediaPlayer::setVolume);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::paintEvent(QPaintEvent*)    //重新定义画布
{
    QPainter paint(this);
    paint.drawPixmap(0,0,width(),height(),QPixmap(":image/picture/background.jpg"));
}

void Widget::on_openfile_pb_clicked()   //打开文件按钮按下
{
    //QMessageBox::information(this,"文件","打开文件");
    //打开对话框,让用户选择音乐的存放路径
    auto path=QFileDialog::getExistingDirectory(this,"选择音乐所在的路径","c:/Users/***/Desktop/music_path");   //打开指定文件夹
//    qInfo()<<path;   //打印刚才打开文件夹
    QDir dir(path);    //
    auto musiclist=dir.entryList(QStringList()<<"*.mp3"<<"*.wav");  //筛出mp3和wav文件
//  qInfo()<<musiclist;  //打印帅选后的音乐
    //把筛选出的文件在listwidget显示出来
    ui->listWidget->addItems(musiclist);
    //默认选择第一首音乐
    ui->listWidget->setCurrentRow(0);
    //把音乐完整路径保存起来
    for(auto file : musiclist)
        playlist.append(QUrl::fromLocalFile(path+"/"+file));  //append附加
//    qInfo()<<playlist;   //将附加的音乐列表打印出来
}


void Widget::on_playorpause_pb_clicked()    //播放或者暂停按下
{
    if(mediaplayer->state()!=QMediaPlayer::PlayingState)  //不处于播放状态
    {
        //得到音乐索引
        int index=ui->listWidget->currentRow();
        //设置音乐路径
        mediaplayer->setMedia(playlist[index]);
    }
    //判断当前状态
    switch(mediaplayer->state())
    {
     case QMediaPlayer::StoppedState:mediaplayer->play();break;
     case QMediaPlayer::PausedState:mediaplayer->play();break;  //停止则播放
     case QMediaPlayer::PlayingState:mediaplayer->pause();break;  //正在播放则暂停
 //    default:mediaplayer->play();break;
    }
}


void Widget::on_lastsong_pb_clicked()      //上一首
{
    int index=ui->listWidget->currentRow();
    if(index==0)    //如果在第一行
        ui->listWidget->setCurrentRow(ui->listWidget->count()-1);
    else
        ui->listWidget->setCurrentRow(index-1);

    mediaplayer->setMedia(playlist[ui->listWidget->currentRow()]);
    mediaplayer->play();
}


void Widget::on_next_song_pb_clicked()    //下一首
{
    int index=ui->listWidget->currentRow();
    if(index == (ui->listWidget->count()-1))  //如果在最后一首歌
        ui->listWidget->setCurrentRow(0);
    else
        ui->listWidget->setCurrentRow(index+1);

    mediaplayer->setMedia(playlist[ui->listWidget->currentRow()]);
    mediaplayer->play();
}



void Widget::on_listWidget_doubleClicked(const QModelIndex &index)    //双击播放指定音乐
{
    mediaplayer->setMedia(playlist[index.row()]);
    mediaplayer->play();
}

void Widget::on_close_pb_clicked()     //离开按钮按下
{
    close();
}


void Widget::on_about_pb_clicked()     //关于按钮按下
{
    QMessageBox::about(this,"关于","应用:本地音乐播放器\r\n版本:1.0.0.0\r\n制作人:GrassFishStudio\r\n时间:2024年3月7日");
}

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

漏洞挖掘 | 没有弱口令的挖掘思路

没有弱口令怎么挖&#xff1f;依稀记得有一个很老的思路叫做禁用js可以跳转后台&#xff0c;奈何学习两年半到现在从未发现一个这种漏洞。 不过&#xff0c;虽然不能直接搞到未授权后台登录&#xff0c;但是站有站的设计&#xff0c;小白有小白的打法&#xff01; 访问某URL&am…

web开发——前端html、css、JavaScript学习总结(持续更新中.......)

目录模版 1 html:结构标签/属性文本标记: mark文本设置:删除线del / 下划线ins/ 加粗b / 强调的文本em / 重要的文本 strong超链接: a联系信息: addressdiv 定义文档中的分区或节: div行元素:spanhtml结构: main / section / articlenav表格:table html中各种标签/属性的英文扩…

ubuntu下vscode+STM32CubeMX+openocd+stlinkv2搭建STM32开发调试下载环境

1、换源 清华源 # 默认注释了源码镜像以提高 apt update 速度&#xff0c;如有需要可自行取消注释 deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse # deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restr…

Flink K8S Operator 离线安装

一 推送镜像 docker pull quay.io/jetstack/cert-manager-cainjector:v1.8.2 docker tag quay.io/jetstack/cert-manager-cainjector:v1.8.2 10.177.85.101:8000/flink/cert-manager-cainjector:v1.8.2 docker push 10.177.85.101:8000/flink/cert-manager-cainjector:v1.8.2d…

大预言模型——ChatGPT,Claude3、Sora、等技术

原文链接&#xff1a;大预言模型——ChatGPT,Claude3、Sora、等技术https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247596849&idx3&sn111d68286f9752008bca95a5ec575bb3&chksmfa823ad6cdf5b3c0c446eceb5cf29cccc3161d746bdd9f26cc060f78c359ec3e2a8f35…

【C语言刷题】——初识位操作符

【C语言刷题】——初识位操作符 位操作符介绍题一、 不创建临时变量&#xff08;第三个变量&#xff09;&#xff0c;实现两个数的交换&#xff08;1&#xff09;法一&#xff08;2&#xff09;法二 题二、 求一个数存储在内存中的二进制中“一”的个数&#xff08;1&#xff0…

浏览器缓存 四种缓存分类 两种缓存类型

浏览器缓存 本文主要包含以下内容&#xff1a; 什么是浏览器缓存按照缓存位置分类 Service WorkerMemory CacheDisk CachePush Cache 按照缓存类型分类 强制缓存协商缓存 缓存读取规则浏览器行为 什么是浏览器缓存 在正式开始讲解浏览器缓存之前&#xff0c;我们先来回顾一…

Mongodb 多条件数组嵌套查询

数据结构&#xff1a; [{"from_site": "sosovalue","id": "e7b0311a8b2f49ec8ba6736980602efc","name": "Daily Total","search_name": "bitcoin spot etf daily total","last_updated…

Kubernetes中pod的创建流程

一般我们在创建pod的过程中都是&#xff0c;执行kubectl命令去apply对应的yaml文件&#xff0c;但是在执行这个操作的过程到pod被完成创建&#xff0c;k8s的组件都做了哪些操作呢&#xff1f;下面我们简要说说pod被创建的过程。 1.用户通过kubectl命名发起请求。 2.apiserver通…

数据结构奇妙旅程之二叉平衡树进阶---AVL树

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …

CountDownLatch介绍和使用

1. CountDownLatch是什么 CountDownLatch 是 Java.util.concurrent 包中的一个同步工具类&#xff0c;用于控制线程的执行顺序。它的主要作用是让一个或多个线程等待其他线程完成操作后再继续执行。 2. CountDownLatch 类常用方法 CountDownLatch(int count) 是 CountDownLa…

Java学习笔记18——SQLite3数据库安装与使用

SQLite 是一个嵌入式 SQL 数据库引擎&#xff0c;它实现了一个自包含、无服务器、零配置、事务性 SQL 数据库引擎。 SQLite 的代码属于公共领域&#xff0c;因此可以免费用于任何商业或私人目的。 SQLite 是世界上部署最广泛的数据库&#xff0c;其应用程序数量之多&#xff0c…

Java随手记

equals和的区别 使用基本数据类型&#xff08;char&#xff0c;int&#xff0c;long等&#xff09;的时候&#xff0c;比较的是它们的值 使用引用数据类型的时候&#xff0c;比较的是地址 equals如果不重写&#xff0c;那么和 是没差别的 下面来看String的比较&#xff0c;这…

图像压缩神器:使用wxPython和Pillow快速压缩JPEG文件

导语&#xff1a; 在数字时代&#xff0c;我们经常处理大量的图像文件&#xff0c;无论是个人照片、网络图片还是工作中的设计素材。然而&#xff0c;随着图像数量的增多&#xff0c;存储和传输这些文件可能会成为一个挑战。幸运的是&#xff0c;我们可以利用Python编程和两个强…

混合测试写一写

题目 服务器IP地址规划&#xff1a;client&#xff1a;12.0.0.12/24&#xff0c;网关服务器&#xff1a;ens36:12.0.0.1/24、ens33&#xff1a;192.168.44.1/24&#xff0c;Web1&#xff1a;192.168.44.30/24&#xff0c;Web2&#xff1a;192.168.44.50/24&#xff0c;Nginx&am…

基于前后端分离技术做增删改查操作(SpringBoot+Mybatis Plus+Vue)

通过SpringBoot后端项目&#xff0c;mybatis plus&#xff0c;和前端Vue来实现前后端分离技术 第一步&#xff1a; 1、准备sql 本项目主要实现两张表的增删改查&#xff08;老师专业&#xff09;分页 CREATE TABLE teacher (id int(11) NOT NULL AUTO_INCREMENT,name varch…

日常超实用技巧(一)

目录 场景说明 mysql解决 excel解决 vscode插件解决 notepad解决 扩展解决 正则解决 自动录制宏解决 场景说明 平常在开发中有时会遇到一些字符串的规整或者格式化的操作,这点在操作数据库时经常常见,但是有的时候却有这种需求,就是我们的修改条件是某个查询条件的字…

第三方软件测评机构出具软件测试报告的流程简析

第三方软件测评机构是独立于软件开发方和需求方的第三者机构&#xff0c;负责对软件进行全面的评估和测试。独立存在使得出具的测试结果会更客观公正。相比之下&#xff0c;软件开发方进行的测评工作往往存在着主观性和局限性&#xff0c;很难全面评估软件的各个方面。 第三方…

Linux操作系统-06-进程与服务管理

使用ps命令查看进程。包括过滤进程信息 使用systemctl命令管理和运行Linux服务 进程&#xff08;Process&#xff09;&#xff1a;操作系统正在运行的应用程序。任意一个进程&#xff0c;都会消耗CPU和内存资源&#xff0c; 服务&#xff08;Service&#xff09;&#xff1a…

C# Onnx C2PNet 图像去雾 室外场景

目录 介绍 效果 模型信息 项目 代码 下载 C# Onnx C2PNet 图像去雾 室外场景 介绍 github地址&#xff1a;https://github.com/YuZheng9/C2PNet [CVPR 2023] Curricular Contrastive Regularization for Physics-aware Single Image Dehazing 效果 模型信息 Model P…
最新文章