#QT(本地音乐播放器)

news2024/7/6 20:03:39

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.coloradmin.cn/o/1510710.html

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

相关文章

012集——显示高考天数倒计时——vba实现

以下代码实现高考倒计时&#xff1a; Sub 高考倒计时() 高考日期 CDate("06,07," & Year(Date)) If Date > 高考日期 Then高考日期 CDate("06-07-" & Year(Date) 1) End If 年月日 Year(Date) & "年" & Month(Date) &am…

鲜花销售小程序|基于微信小程序的鲜花销售系统设计与实现(源码+数据库+文档)

鲜花销售小程序目录 目录 基于微信小程序的鲜花销售系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1前台功能模块 2、后台功能模块 1、管理员功能模块 四、数据库设计 1、实体ER图 2、具体的表设计如下所示&#xff1a; 五、核心代码 六、论文参考 七、…

LabVIEW多表位数字温湿度计图像识别系统

LabVIEW多表位数字温湿度计图像识别系统 解决数字温湿度计校准过程中存在的大量需求和长时间校准问题&#xff0c;通过LabVIEW开发平台设计了一套适用于20多个表位的数字温度计图像识别系统。该系统能够通过图像采集、提取和处理&#xff0c;进行字符训练&#xff0c;从而实现…

LiveGBS流媒体平台GB/T28181功能-海康摄像头国标语音对讲大华摄像头国标语音对讲GB28181语音对讲需要的设备及服务准备

LiveGBS海康摄像头国标语音对讲大华摄像头国标语音对讲GB28181语音对讲需要的设备及服务准备 1、背景2、准备2.1、服务端必备条件&#xff08;注意&#xff09;2.2、准备语音对讲设备2.2.1、 大华摄像机2.2.1.1、 配置接入示例2.2.1.2、 配置音频通道编号 2.2.2、 海康摄像机2.…

现货黄金交易网上有用的交易技巧

在不同的现货黄金交易网上&#xff0c;经常有投资者分享交易技巧。由于在网上发文没什么限制&#xff0c;所以这些交易技巧都是泥沙俱下&#xff0c;质量良莠不齐。不过也有一些是有用的&#xff0c;下面我们就来介绍一下现货黄金交易网上那些有用的交易技巧。 培养防守意识。什…

swiftUI中的可变属性和封装

swiftUI的可变属性 关于swift中的属性&#xff0c;声明常量使用let &#xff0c; 声明变量使用var 如果需要在content中更改视图变化那么就需要在 var前面加上state 。 通过挂载到state列表 &#xff0c;从而让xcode找到对应的改变的值 例子&#xff1a; import SwiftUIstruc…

Java后端八股------消息中间件篇

自动确认没收到&#xff0c;实现重复消费问题&#xff0c;可以用业务唯一标识来确定业务是否被消费。 TTL也就是超时时间&#xff0c;一般去dead letter的时间为min(消息的ttl,queue的ttl)。 acksall设置是最安全的&#xff0c;但是效率太低了&#xff0c;实际的生…

App自动化测试环境搭建(详细版)

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 只做记录和注意点&#xff0c;详细内容不做解释 环境&#xff1a;winappium夜神模拟器python 需…

企业电子招投标系统源码-从源码到实践:深入了解鸿鹄电子招投标系统与电子招投标

在数字化采购领域&#xff0c;企业需要一个高效、透明和规范的管理系统。通过采用Spring Cloud、Spring Boot2、Mybatis等先进技术&#xff0c;我们打造了全过程数字化采购管理平台。该平台具备内外协同的能力&#xff0c;通过待办消息、招标公告、中标公告和信息发布等功能模块…

echarts绘制雷达图

<template><div><div>【云端报警风险】</div><div ref"target" class"w-full h-full" stylewidth&#xff1a;200px;height:300px></div></div> </template><script setup> import { ref, onMounte…

11 | 怎么给字符串字段加索引?

现在&#xff0c;几乎所有的系统都支持邮箱登录&#xff0c;如何在邮箱这样的字段上建立合理的索引&#xff0c;是我们今天要讨论的问题。 假设&#xff0c;你现在维护一个支持邮箱登录的系统&#xff0c;用户表是这么定义的&#xff1a; mysql> create table SUser( ID bi…

安科瑞温湿度控制器怎么安装?

WH-M 温湿度模块主要用于中高压开关柜、端子箱、环网柜、箱变等设备内部温度和湿度的检测。该模块 采用专用外壳&#xff0c;通风效果好&#xff0c;外观精致&#xff0c;既能有效保护内部元件&#xff0c;提高使用寿命&#xff0c;又方便安装、接线。 接线方式

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

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

3588板子部署yoloV5

一 &#xff1a;准备 ubuntu linux X86_64系统 a.安装anaconda b.创建虚拟环境 python3.8 二&#xff1a; 下载rknn-toolkit2 传送门 unzip 解压文件夹 三&#xff1a;pt转onnx模型 四&#xff1a;onnx转rknn模型 a:cd到rknn-toolkit2-master/rknn-toolkit2/packag…

使用Java的等待/通知机制实现一个简单的阻塞队列

Java的等待/通知机制 Java的等待通知机制是多线程间进行通信的一种方式。 有三个重要的方法&#xff1a;wait()&#xff0c;notify() 和以及notifyAll() wait()&#xff1a;该方法用于让当前线程&#xff08;即调用该方法的线程&#xff09;进入等待状态并且释放掉该对象上的…

初级爬虫实战——伯克利新闻

文章目录 发现宝藏一、 目标二、简单分析网页1. 寻找所有新闻2. 分析模块、版面和文章 三、爬取新闻1. 爬取模块2. 爬取版面3. 爬取文章 四、完整代码五、效果展示 发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不…

leetcode 热题 100_螺旋矩阵

题解一&#xff1a; 模拟&#xff1a;定义四个边界&#xff0c;指针按右下左上的顺序遍历&#xff0c;每遍历一条边&#xff0c;边界就减一&#xff0c;并且在某个方向没有可以遍历的数时直接返回。 import java.util.ArrayList; import java.util.List;class Solution {publi…

探索ChatGPT的前沿科技:解锁其在地理信息系统、气候预测、农作物生长等关键领域的创新应用

以ChatGPT、LLaMA、Gemini、DALLE、Midjourney、Stable Diffusion、星火大模型、文心一言、千问为代表AI大语言模型带来了新一波人工智能浪潮&#xff0c;可以面向科研选题、思维导图、数据清洗、统计分析、高级编程、代码调试、算法学习、论文检索、写作、翻译、润色、文献辅助…

云仓酒庄2024市场活动:稳扎稳打,继续前行,以消费者为中心

云仓酒庄2024市场活动&#xff1a;稳扎稳打&#xff0c;继续前行&#xff0c;以消费者为中心 随着酒类市场的日益繁荣与多样化&#xff0c;云仓酒庄&#xff0c;始终将消费者的需求与满意度置于首位。2024年&#xff0c;云仓酒庄将围绕消费者需求&#xff0c;继续深化市场活动…

未来艺术展览新趋势——3D线上画展如何创新展示?

一、艺术展示的数字化转型 随着科技的不断进步&#xff0c;3D线上画展作为艺术展示的新趋势&#xff0c;正逐渐改变着人们欣赏和购买艺术作品的方式。对于画家而言&#xff0c;3D线上画展不仅提供了一个全新的平台来展示他们的作品&#xff0c;还开辟了销售渠道&#xff0c;扩大…