Qt 项目实战 | 音乐播放器

news2024/11/26 13:28:46

Qt 项目实战 | 音乐播放器

  • Qt 项目实战 | 音乐播放器
    • 播放器整体架构
    • 创建播放器主界面

官方博客:https://www.yafeilinux.com/

Qt开源社区:https://www.qter.org/

参考书:《Qt 及 Qt Quick 开发实战精解》

Qt 项目实战 | 音乐播放器

开发环境:Qt Creator 3.3.0 + Qt 4.8.6

在这里插入图片描述

播放器整体架构

在这里插入图片描述

创建播放器主界面

新建 Qt Gui 应用,项目名 myPlayer,基类为 QWidget,类名为 MyWidget。

添加资源文件 myImages,前缀为空,将 images 中的所有图片都添加进去。

在这里插入图片描述

myPlayer.pro 添加代码:

QT += phonon

在 mywidget.h 添加头文件和类前置声明:

#include <phonon>

class QLabel;

添加私有变量、函数:

Phonon::MediaObject *mediaObject;
QAction *playAction;
QAction *stopAction;
QAction *skipBackwardAction;
QAction *skipForwardAction;
QLabel *topLabel;
QLabel *timeLabel;

void initPlayer();

添加私有槽:

private slots:
    void updateTime(qint64 time);
    void setPaused();
    void skipBackward();
    void skipForward();
    void openFile();
    void setPlaylistShown();
    void setLrcShown();

在 mywidget.cpp 中添加头文件:

#include <QLabel>
#include <QToolBar>
#include <QVBoxLayout>
#include <QTime>

在构造函数中添加代码:

initPlayer();

添加 initPlayer() 函数的定义:

// 初始化播放器
void MyWidget::initPlayer()
{
    // 设置主界面标题、图标和大小
    setWindowTitle(tr("音乐播放器"));
    setWindowIcon(QIcon(":/images/icon.png"));
    setMinimumSize(320, 160);
    setMaximumSize(320, 160);

    // 创建媒体图
    mediaObject = new Phonon::MediaObject(this);
    Phonon::AudioOutput* audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this);
    Phonon::createPath(mediaObject, audioOutput);

    // 关联媒体对象的tick()信号来更新播放时间的显示
    connect(mediaObject, SIGNAL(tick(qint64)), this, SLOT(updateTime(qint64)));

    // 创建顶部标签,用于显示一些信息
    topLabel = new QLabel(tr("<a href = \" https://blog.csdn.net/ProgramNovice \"> https://blog.csdn.net/ProgramNovice </a>"));
    topLabel->setTextFormat(Qt::RichText);
    topLabel->setOpenExternalLinks(true);
    topLabel->setAlignment(Qt::AlignCenter);

    // 创建控制播放进度的滑块
    Phonon::SeekSlider* seekSlider = new Phonon::SeekSlider(mediaObject, this);

    // 创建包含播放列表图标、显示时间标签和桌面歌词图标的工具栏
    QToolBar* widgetBar = new QToolBar(this);
    // 显示播放时间的标签
    timeLabel = new QLabel(tr("00:00 / 00:00"), this);
    timeLabel->setToolTip(tr("当前时间 / 总时间"));
    timeLabel->setAlignment(Qt::AlignCenter);
    timeLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    // 创建图标,用于控制是否显示播放列表
    QAction* PLAction = new QAction(tr("PL"), this);
    PLAction->setShortcut(QKeySequence("F4"));
    PLAction->setToolTip(tr("播放列表(F4)"));
    connect(PLAction, SIGNAL(triggered()), this, SLOT(setPlaylistShown()));
    // 创建图标,用于控制是否显示桌面歌词
    QAction* LRCAction = new QAction(tr("LRC"), this);
    LRCAction->setShortcut(QKeySequence("F2"));
    LRCAction->setToolTip(tr("桌面歌词(F2)"));
    connect(LRCAction, SIGNAL(triggered()), this, SLOT(setLrcShown()));
    // 添加到工具栏
    widgetBar->addAction(PLAction);
    widgetBar->addSeparator();
    widgetBar->addWidget(timeLabel);
    widgetBar->addSeparator();
    widgetBar->addAction(LRCAction);

    // 创建播放控制动作工具栏
    QToolBar* toolBar = new QToolBar(this);
    // 播放动作
    playAction = new QAction(this);
    playAction->setIcon(QIcon(":/images/play.png"));
    playAction->setText(tr("播放(F5)"));
    playAction->setShortcut(QKeySequence(tr("F5")));
    connect(playAction, SIGNAL(triggered()), this, SLOT(setPaused()));
    // 停止动作
    stopAction = new QAction(this);
    stopAction->setIcon(QIcon(":/images/stop.png"));
    stopAction->setText(tr("停止(F6)"));
    stopAction->setShortcut(QKeySequence(tr("F6")));
    connect(stopAction, SIGNAL(triggered()), mediaObject, SLOT(stop()));
    // 跳转到上一首动作
    skipBackwardAction = new QAction(this);
    skipBackwardAction->setIcon(QIcon(":/images/skipBackward.png"));
    skipBackwardAction->setText(tr("上一首(Ctrl+Left)"));
    skipBackwardAction->setShortcut(QKeySequence(tr("Ctrl+Left")));
    connect(skipBackwardAction, SIGNAL(triggered()), this, SLOT(skipBackward()));
    // 跳转到下一首动作
    skipForwardAction = new QAction(this);
    skipForwardAction->setIcon(QIcon(":/images/skipForward.png"));
    skipForwardAction->setText(tr("下一首(Ctrl+Right)"));
    skipForwardAction->setShortcut(QKeySequence(tr("Ctrl+Right")));
    connect(skipForwardAction, SIGNAL(triggered()), this, SLOT(skipForward()));
    // 打开文件动作
    QAction* openAction = new QAction(this);
    openAction->setIcon(QIcon(":/images/open.png"));
    openAction->setText(tr("播放文件(Ctrl+O)"));
    openAction->setShortcut(QKeySequence(tr("Ctrl+O")));
    connect(openAction, SIGNAL(triggered()), this, SLOT(openFile()));
    // 音量控制部件
    Phonon::VolumeSlider* volumeSlider = new Phonon::VolumeSlider(audioOutput, this);
    volumeSlider->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
    // 添加到工具栏
    toolBar->addAction(playAction);
    toolBar->addSeparator();
    toolBar->addAction(stopAction);
    toolBar->addSeparator();
    toolBar->addAction(skipBackwardAction);
    toolBar->addSeparator();
    toolBar->addAction(skipForwardAction);
    toolBar->addSeparator();
    toolBar->addWidget(volumeSlider);
    toolBar->addSeparator();
    toolBar->addAction(openAction);

    // 创建主界面布局管理器
    QVBoxLayout* mainLayout = new QVBoxLayout;
    mainLayout->addWidget(topLabel);
    mainLayout->addWidget(seekSlider);
    mainLayout->addWidget(widgetBar);
    mainLayout->addWidget(toolBar);
    setLayout(mainLayout);

    mediaObject->setCurrentSource(Phonon::MediaSource("../myPlayer/music.mp3"));
}

添加 updateTime(qint64 time) 槽的定义:

// 更新 timeLabel 标签显示的播放时间
void MyWidget::updateTime(qint64 time)
{
    qint64 totalTimeValue = mediaObject->totalTime();
    QTime totalTime(0, (totalTimeValue / 60000) % 60, (totalTimeValue / 1000) % 60);
    QTime currentTime(0, (time / 60000) % 60, (time / 1000) % 60);
    QString str = currentTime.toString("mm:ss") + " / " + totalTime.toString("mm:ss");
    timeLabel->setText(str);
}

添加 setPaused() 槽的定义:

// 播放或者暂停
void MyWidget::setPaused()
{
    // 如果先前处于播放状态,那么暂停播放;否则,开始播放
    if (mediaObject->state() == Phonon::PlayingState)
        mediaObject->pause();
    else
        mediaObject->play();
}

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

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

相关文章

揭开堆叠式自动编码器的强大功能

一、介绍 在不断发展的人工智能和机器学习领域&#xff0c;深度学习技术因其处理复杂和高维数据的能力而广受欢迎。在各种深度学习模型中&#xff0c;堆叠式自动编码器是一种多功能且功能强大的工具&#xff0c;可用于特征学习、降维和数据表示。本文探讨了堆叠式自动编码器在深…

UE5、CesiumForUnreal实现加载GeoJson绘制单面(Polygon)功能(StaticMesh方式)

文章目录 1.实现目标2.实现过程2.1 实现原理2.1.1 数据读取2.1.2 三角剖分2.1.3 创建StaticMesh2.2 应用测试2.2.1 具体代码2.2.2 蓝图应用测试3.参考资料1.实现目标 通过读取本地GeoJson数据,在UE中以StaticMeshComponent的形式绘制出面数据,支持Editor和Runtime环境,GIF动…

高压放大器能够在哪里使用呢

高压放大器是一种重要的电子设备&#xff0c;可以在许多不同的领域和应用中使用。下面西安安泰将详细介绍高压放大器的应用。 医学影像&#xff1a;高压放大器在医学影像领域具有广泛的应用。医学影像设备&#xff08;如X射线机、CT扫描仪等&#xff09;需要高压来产生足够的能…

通俗理解repartition和coalesce区别

官方的解释 reparation 返回一个具有恰好numPartitions分区的新RDD。 可以增加或减少此RDD中的并行级别。在内部,reparation会使用shuffle来重新分发的数据。 如果要减少此RDD中的分区数量,请考虑使用coalesce,这样可以避免执行shuffle。 coalesce 返回一个新的RDD,该RDD被…

nginx--install

1. ubuntu 1.1 下载并解压依赖 每个包去各自官网下载 stable 版就行。 tar xzvf nginx-1.24.0.tar.gz tar xzvf openssl-3.1.4.tar.gz tar xzvf pcre2-10.42.tar.gz tar xzvf zlib-1.3.tar.gz1.2 配置及安装 参数含义详见 nginx 官网 cd nginx-1.24.0./configure --pre…

11 抽象向量空间

抽象向量空间 向量是什么函数什么是线性推论向量空间 这是关于3Blue1Brown "线性代数的本质"的学习笔记。 向量是什么 可以是一个箭头&#xff0c;可以是一组实数&#xff0c;即一个坐标对。 箭头在高维&#xff08;4维&#xff0c;甚至更高&#xff09;空间&…

免费音效素材,不能错过这6个网站

找免费音效素材&#xff0c;那必须要上这6个网站&#xff0c;热门音效、BGM都能免费下载&#xff0c;赶紧收藏起来。 1、菜鸟图库 https://www.sucai999.com/audio.html?vNTYwNDUx 菜鸟图库是一个综合性素材网站&#xff0c;站内涵盖设计、图片、办公、视频、音效等素材。其中…

【23真题】Easy!速成120两个月够了!

今天分享的是23年广西科技809的信号与系统试题及解析。 本套试卷难度分析&#xff1a;本套试题内容难度中等偏下&#xff0c;题量不大&#xff0c;考察的知识点很基础。所有的知识点都出现在它应该出现的地方&#xff0c;无任何偏难怪&#xff0c;非常常规的试卷&#xff01;个…

经典OJ题:链表中的倒数第K个节点

题目&#xff1a; 输入一个链表&#xff0c;输出该链表中倒数第k个结点。 题源&#xff1a;链表中倒数第k个结点_牛客题霸_牛客网 (nowcoder.com) 方法一&#xff1a;暴力求解法 可以线统计链表的节点个数&#xff0c;然后用链表节点的个数减去K&#xff0c;得出倒数第K个节点…

【EI会议征稿】第四届智慧城市工程与公共交通国际学术会议(SCEPT 2024)

第四届智慧城市工程与公共交通国际学术会议&#xff08;SCEPT 2024&#xff09; 2024 4th International Conference on Smart City Engineering and Public Transportation 第四届智慧城市工程与公共交通国际学术会议&#xff08;SCEPT 2024&#xff09;将于2024年1月26-28日…

免交互(粗糙版)

免交互&#xff1a; 交互是&#xff1a;计算机播放器&#xff0c;需要放视频&#xff0c;我发出指令&#xff0c;计算机执行指令&#xff0c;做出相应的动作。比如说播放视频音频的动作 Linux系统中的交互是,例如&#xff1a;passwd 尤其在shell脚本中&#xff0c;我们的运行…

华为荣耀软开秋招面经问题整理

一、八股 1.linux常用命令 Linux常用命令&#xff08;面试题&#xff09;_linux常用命令面试题-CSDN博客 常用命令、系统命令、打包命令、vim、开关机命令 2.socket通信调用api过程 TCP UDP 二、算法 1.LeetCode——240 搜索二维矩阵II-CSDN博客 2.最长递增子序列的三种…

spring-clound基础开发

一、使用openfeig调用远程另外一个服务接口 1、创建一个spring boot工程,并且创建2个模块来当微服务模块 2、分别配置2个模块的启动文件 3、分别两个模块下创建一个测试的控制器 4、在项目的根目录的pom.xml中添加spring-cloud配置 <properties><java.version>1…

2023-11-7 OpenAI 45 分钟发布会:整理发布了哪些内容更新

本心、输入输出、结果 文章目录 2023-11-7 OpenAI 45 分钟发布会&#xff1a;整理发布了哪些内容更新前言发布 GPT-4 Turbo价格问题 推出 OpenAI 推出了「GPTs」六大升级上下文长度升级API 和函数调用控制手段增强模型内部和外部知识库的升级多模态模型微调与定制更高的使用频率…

Linux shell编程学习笔记22: () $() (()) 的用法小结

最近学习Linux Shell编程&#xff0c;对 () (()) [] [[]]等符号的用法还是有点分不太清楚&#xff0c;于是决定再梳理一下。今天先整理 () $() (()) 的用法。 1 单小括号() 1.1 子shell&#xff08;命令组&#xff09; 括号中的命令将会新开一个子shell顺序执行&#xff0c;所…

Web逆向-mtgsig1.2简单分析

{"a1": "1.2", # 加密版本"a2": new Date().valueOf() - serverTimeDiff, # 加密过程中用到的时间戳. 这次服主变坏了, 时间戳需要减去一个 serverTimeDiff(见a3) ! "a3": "这是把xxx信息加密后提交给服务器, 服主…

马斯克:让我成功的其实是“第一性原理”(PM必读)

大家好&#xff0c;我是老原。 关注我比较久的老粉都知道&#xff0c;我是从产品经理转到项目经理&#xff0c;然后才到现在的PMO。 在做产品的时&#xff0c;关注点在于如何把产品做好&#xff0c;在接触到项目后&#xff0c;更多的是去关注如何把项目做好&#xff0c;也是出…

服务号怎么改成订阅号

服务号和订阅号有什么区别&#xff1f;服务号转为订阅号有哪些作用&#xff1f;在推送频率上来看&#xff0c;服务号每月能推送四条消息&#xff0c;而订阅号可以每天&#xff08;24小时&#xff09;推送一条消息。如果企业开通公众号的目的是提供服务&#xff0c;例如售前资讯…

详解--Hash(中文也称散列、哈希)

参考链接 参考链接2 1. hash 概念 1.1 什么是 hash Hash 也称散列、哈希&#xff0c;对应的英文都是 Hash。 基本原理就是把任意长度的输入&#xff0c;通过 Hash 算法变成固定长度的输出。这个映射的规则就是对应的 Hash 算法&#xff0c;而原始数据映射后的二进制串就是哈希…

alpha融合详解(alpha compositing)

alpha融合简介 alpha融合&#xff08;alpha compositing&#xff09;是图像处理中常用技术&#xff0c;常见的公式如下&#xff1a; C O α C A ( 1 − α ) C B (1) C_O \alpha C_A (1-\alpha)C_B \tag{1} CO​αCA​(1−α)CB​(1) 其中 C A C_A CA​&#xff0c; C B C…