SDUc++课结课大作业:基于qt类库c++实现简单的音乐播放器

文章目录

  • 前言
  • 一、实现功能
  • 二、研发进度记录
    • 环境配置
    • **系统环境配置**
    • qt类库下载
    • devc++的软件编译配置
    • 1.最终效果及全部代码
    • 2.file按钮打开文件
    • 3. listWidget详解
    • 4.slider控制音乐播放进度
    • 5.多选文件添加到listWidget中
    • 6.播放暂停按钮
    • 7.进度显示,怎么转换成 分:秒的形式
    • 8.双击歌曲名播放音乐
    • 9.上一曲、下一曲
    • 10.playMode播放模式切换
    • 11.main函数传参实现打开方式的选择
    • 细节 1. 去掉控制台
    • 细节 2. exe版本发布
    • 细节3.LAV audio解码器
  • 总结


前言

本篇博客介绍如何基于qt5制作简单音乐播放器

开发工具:devc++
实现语言:c++
需导入qt5这个库

**


以下是本篇文章正文内容

一、实现功能

  1. 拥有菜单或工具条(不要求两者都有)
  2. 播放按钮,暂停功能
  3. 通过滑动条显示进度
  4. 标签显示进度时间
  5. 可以用鼠标拖动滑块改变播放进度
  6. 可播放音频,也可以播放视频。播放音频时,标签大字显示歌曲名,播放视频时,视频名称显示在底部QStatusBar上(自行搜索用法)。
  7. 双击音频文件,可以自动打开本媒体播放器进行播放。
  8. 通过QFileDialog一次打开多个媒体文件放入QListWidget,并可以通过双击激发列表项进行播放。该功能并非硬性要求,但完成该功能的可得高分。
  9. 并且提供进度显示,还可以通过拖动进度条来变换播放位置。
  10. 上一曲,下一曲,播放模式切换。
  11. 设计具有一定实用性的媒体播放器,其中视频用QGraphicsVideoItem显示。

二、研发进度记录

环境配置

系统环境配置

SDUc++课结课大作业:基于qt类库c++实现简单的音乐播放器_第1张图片

qt类库下载

从以下链接下载QT类库的在线安装程序: 链接:https://pan.baidu.com/s/1mZK_3-9f23455gyxljmrkQ
提取码:2019

或者从以下网站下载在线安装文件4.1.1版本,点击执行进行安装。 Download Qt: Get Qt Online Installer
安装过程中需要注册,请按照要求注册。然后输入Email和密码进入下一步
这里是引用


devc++的软件编译配置


在DEV C++菜单中选择Tools,Compiler Options,在弹出的窗口中,点击右上方带加号的按钮(Add a blank compiler set),然后输入新编译器名字,比如MinGW810_64 Compiler,点击OK退出。在General中勾选Add the following commands when calling the compile,然后复制以下内容在方框中:-O2 -lqt5core -lqt5widgets -lqt5gui -lQt5Multimedia -lQt5MultimediaWidgets -lQt5Network -lQt5TextToSpeech -lQt5Charts -lQt5DataVisualization
SDUc++课结课大作业:基于qt类库c++实现简单的音乐播放器_第2张图片
SDUc++课结课大作业:基于qt类库c++实现简单的音乐播放器_第3张图片
SDUc++课结课大作业:基于qt类库c++实现简单的音乐播放器_第4张图片
SDUc++课结课大作业:基于qt类库c++实现简单的音乐播放器_第5张图片
SDUc++课结课大作业:基于qt类库c++实现简单的音乐播放器_第6张图片
SDUc++课结课大作业:基于qt类库c++实现简单的音乐播放器_第7张图片

1.最终效果及全部代码

SDUc++课结课大作业:基于qt类库c++实现简单的音乐播放器_第8张图片
SDUc++课结课大作业:基于qt类库c++实现简单的音乐播放器_第9张图片
代码如下
.h文件:

#ifndef LESPLAYER_H
#define LESPLAYER_H

#include  //包含QtWidgets头文件
#include //包含播放器头文件
#include  //包含视频项头文件

class MyGraphicsView:public QGraphicsView
{
	public:
		MyGraphicsView(QWidget *parent = 0); //构造函数,参数是父窗体指针,默认是0,即没有父窗口
		QGraphicsScene *scene=new QGraphicsScene; //定义场景,用于放置视频项
		QGraphicsVideoItem *videoItem=new QGraphicsVideoItem; //定义一个视频窗口	
	private:
		void resizeEvent(QResizeEvent *event);//视图窗口尺寸改变时自动执行的函数
};

class MyMainWindow:public QMainWindow //定义一个MyMainWindow类,继承自QMainWindow窗口类
{
	public:
		MyMainWindow(QWidget *parent = 0); //构造函数,参数是父窗体指针
		QMenuBar *menuBar=new QMenuBar;//定义菜单栏对象指针menuBar
		QMediaPlayer *player=new QMediaPlayer(this); //定义一个播放器对象指针
		MyGraphicsView *view=new MyGraphicsView; //定义视图窗口,用于观看视频
		//Layout
		QHBoxLayout *hLayout = new QHBoxLayout;//存放进度条的
		QHBoxLayout *ListLayout = new QHBoxLayout;//歌曲列表list
		QHBoxLayout *buttonLayout = new QHBoxLayout;//开始、暂停、上下一首
		QHBoxLayout *name_list = new QHBoxLayout;//歌曲名-播放进度条-列表
		QVBoxLayout *verticalLayout = new QVBoxLayout;//整个的垂直结构
		QVBoxLayout *play_slider = new QVBoxLayout;
		//Slider
		QSlider *slider=new QSlider; //创建QSlider对象指针
		//ListWidget
		QWidget *centralWidget=new QWidget;//定义一个QWidget对象指针centralWidget
		QListWidget *listWidget = new QListWidget;//列表窗
		//Label
		QLabel *timeLabel = new QLabel;//显示实时的时间
		QLabel *durationLabel = new QLabel;//显示总时间
		QLabel *songName = new QLabel;//歌名标签
		//Button
		QPushButton *startButton = new QPushButton;//播放按钮
		QPushButton *nextLButton = new QPushButton;//左按钮
		QPushButton *nextRButton = new QPushButton;//右按钮
		QPushButton *importMusic = new QPushButton;//右按钮
		QPushButton *playMode =  new QPushButton;//模式切换按钮
		//标志
		int flag = 1;//播放暂停按钮播放控制
		int playNow = 0;//正在播放曲目控制
		int Mode = 1;//播放模式控制标志
		void listWidgetItemActivated(QListWidgetItem *activatedItem); //item列表项被激发以后的处理函数
		void openFile(); //点击open菜单项时的处理函数
		void openMusic();//打开音乐
		void videoPositionChanged(double position);//进度变化
		void durationChanged(double duration);//获取总时间
		void mediaStatusChanged(QMediaPlayer::MediaStatus statu); //让歌曲进度随进度条变化而改变
		void sliderMovedEvent();//
		void sliderReleasedEvent();
		void sliderPressedEvent();
		void startButtonEvent();//播放
		void pauseButtonEvent();//暂停
		void stopButtonEvent();//停止
		void importLocalSongs();//导入本地音乐
		void lastMusic();//上一曲
		void nextMusic();//下一曲
		void changeList();//列表变化
		void changeMode();//播放模式改变
		void inputInformation();//错误提示
		int generateRandomNumber();
};

#endif // LESPLAYER_H

.cpp文件

#include "LesPlayer.h"
#define cn QString::fromLocal8Bit //中文字符显示
MyGraphicsView::MyGraphicsView(QWidget *parent):QGraphicsView(parent)
{
	this->setStyleSheet("background-color:rgb(232,255,255);");//通过样式表设置背景色
	this->setContentsMargins(0,0,0,0); //设定边界宽度是0
	this->setFocusPolicy(Qt::NoFocus); //设置本控件不接收焦点
	this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); //禁止水平滚动条显示
	this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);	//禁止垂直滚动条显示
	this->setMinimumSize(QSize(520,280));//设置窗口最小尺寸
	this->setScene(scene); //设置视图窗口要观看的场景为scene
	scene->addItem(videoItem); //添加视频项videoItem到场景scene
}
void MyGraphicsView::resizeEvent(QResizeEvent *event)
{
	scene->setSceneRect(0, 0, this->width(), this->height()); //设置场景scene的显示坐标范围和视图窗口相同
	videoItem->setSize(QSize(this->width(), this->height())); //设置视频项的大小和场景一致。
}
//定义构造函数,参数是父窗体指针,先调用基类构造函数QMainWindow(parent)
MyMainWindow::MyMainWindow(QWidget *parent):QMainWindow(parent)
{
	this->setWindowTitle("Libin Music"); //设置窗体的标题
	this->resize(960,600); 		//变更窗体尺寸
	this->setMenuBar(menuBar); //menuBar设置为本窗口的菜单栏
	this->setCentralWidget(centralWidget);//设置一个widget
	this->setWindowIcon(QPixmap("logoIcon.png"));//窗口图标
	//定义菜单对象指针fileMenu,显示“File”
	QMenu *fileMenu=new QMenu("File"); 
	//为fileMen添加一个菜单项,有图标和点击时的处理函数openFile();
	fileMenu->addAction(QPixmap("open.png"), "OpenVideo", this, &openFile); 
	fileMenu->addAction(QPixmap("open.png"), "OpenMusic", this, &openMusic); 
	menuBar->addMenu(fileMenu); //将fileMenu菜单添加到菜单栏
	//进度条管理
	slider->setRange(1,100); //设定数据范围
	slider->setSingleStep(5); //设定单次步长
	slider->setPageStep(5); //设定PageUp和PageDown步长
	slider->setFixedWidth(600); //设定控件固定宽度
	slider->setOrientation(Qt::Horizontal); //设定控件显示方位
	//下一曲按钮
	QPixmap nextRicon(tr("next.png"));
  	nextRButton->setIcon(nextRicon);
 	nextRButton->setFixedSize(nextRicon.size());
	nextRButton->setStyleSheet("background-color:rgb(20,145,168);""color:rgb(248,244,237);");
	nextRButton->setCursor(Qt::PointingHandCursor);
	//开始按钮设置
	QPixmap pauseIcon(tr("play4.png"));
    startButton->setIcon(pauseIcon);
 	startButton->setFixedSize(nextRicon.size());
	startButton->setStyleSheet("background-color:rgb(20,145,168);""color:rgb(248,244,237);");
	startButton->setCursor(Qt::PointingHandCursor);
	//上一曲按钮
	QPixmap nextLicon(tr("last.png"));
  	nextLButton->setIcon(nextLicon);
 	nextLButton->setFixedSize(nextLicon.size());
	nextLButton->setStyleSheet("background-color:rgb(20,145,168);""color:rgb(248,244,237);");
	nextLButton->setCursor(Qt::PointingHandCursor);
	//导入音乐列表
	QPixmap ListIcon(tr("menu.png"));
  	importMusic->setIcon(ListIcon);
 	importMusic->setFixedSize(80,80);
	importMusic->setStyleSheet("background-color:rgb(20,145,168);""color:rgb(20,145,168);");
	importMusic->setCursor(Qt::PointingHandCursor);
	QString str=QString(cn("导入本地音乐\n"));
	importMusic->setToolTip(str);
	//模式切换按钮
	playMode->setIcon(QPixmap("Sequential.png"));
	playMode->setFixedSize(nextLicon.size());
	playMode->setStyleSheet("background-color:rgb(20,145,168);""color:rgb(20,145,168);");
	playMode->setCursor(Qt::PointingHandCursor);
	//歌曲名label
	songName->setMinimumSize(120,80);
	songName->setMaximumSize(120,80);//固定大小,防止乱跑
	songName->setText(cn("音乐的力量"));
	songName->setAlignment(Qt::AlignCenter | Qt::AlignHCenter);
	songName->setStyleSheet("background-color:rgb(20,145,168);""color:rgb(248,244,237);");
	songName->setWordWrap(true);//Label内容换行
	//进度时间层
	hLayout->addWidget(timeLabel);
	hLayout->addWidget(slider);
	hLayout->addWidget(durationLabel);
	//按钮层添加按钮
	buttonLayout->addWidget(playMode);//播放模式
	buttonLayout->addWidget(nextLButton);
	buttonLayout->addWidget(startButton);
	buttonLayout->addWidget(nextRButton);
	//play_slider 上播放按钮,下进度条
	play_slider->addLayout(buttonLayout);
	play_slider->addLayout(hLayout);
	//name_list歌曲名-播放进度条-列表
	name_list->addWidget(songName);
	name_list->addLayout(play_slider);
	name_list->addWidget(importMusic);
	//列表窗
	ListLayout->addWidget(listWidget);
	//垂直结构添加
	verticalLayout->addLayout(ListLayout);
	verticalLayout->addLayout(name_list);
	//添加垂直结构
	centralWidget->setLayout(verticalLayout);
	//播放器进度改变信号以及该信号的处理函数
	connect(player, &QMediaPlayer::positionChanged, this, &videoPositionChanged);
	//打开媒体文件时,player播放器会发出媒体总长度改变信号,用此信号设置滑动条最大值
	connect(player, &QMediaPlayer::durationChanged, this, &durationChanged);
	//播放器的媒体状态改变信号以及该信号处理函数
	connect(player, &QMediaPlayer::mediaStatusChanged, this, &mediaStatusChanged);
	//进度条和媒体播放链接起来
	connect(slider, &QSlider::sliderMoved, this, &sliderMovedEvent);
	//检测释放进度条
	connect(slider, &QSlider::sliderReleased, this, &sliderReleasedEvent);
	//检测按压进度条
	connect(slider, &QSlider::sliderPressed, this, &sliderPressedEvent);
	//播放、暂停按钮
	connect(startButton,&QPushButton::clicked, this, &startButtonEvent);
	//下一曲
	connect(nextRButton,&QPushButton::clicked, this, &nextMusic);
	//上一曲
	connect(nextLButton,&QPushButton::clicked, this, &lastMusic);
	//建立itemActivated列表项激发信号和信号处理函数之间的连接
	connect(listWidget, &QListWidget::itemActivated, this, &listWidgetItemActivated);
	//导入音乐
	connect(importMusic,&QPushButton::clicked, this, &importLocalSongs);
	//播放模式
	connect(playMode,&QPushButton::clicked, this, &changeMode);
}
//列表同步变化
void MyMainWindow::changeList(){
	for (int i=0; i<listWidget->count(); i++)//遍历列表框的所有项,设置背景色和前景色,更改图标
	{
		listWidget->item(i)->setForeground(QColor(0, 0, 0));
		listWidget->item(i)->setBackground(QColor(255, 255, 255));	
		listWidget->item(i)->setIcon(QPixmap("MultiMedia 32p-3.ico"));
	}
	listWidget->item(playNow)->setForeground(QColor(255, 0, 0)); 
	listWidget->item(playNow)->setBackground(QColor(0, 255, 0));
	listWidget->item(playNow)->setIcon(QPixmap("play2.png"));
	//下面是列表显示的同步设置
	QString musicFullName = listWidget->item(playNow)->data(Qt::UserRole).toString(); 
	QFileInfo fileInfo(musicFullName); //创建文件信息类对象fileInfo
	QString fileName=fileInfo.fileName(); //从fileInfo中获得文件名(无路径)
	songName->setText(fileName);
	//开始按钮同步
    startButton->setIcon(QPixmap("play2.png"));
	flag = 1;
}
//滑动条最大值
void MyMainWindow::durationChanged(double duration) 
{
	slider->setMaximum(duration); //设置滑动条最大值
	int min = duration/1000/60;//分钟
	int s = (duration/1000/60 - min)*60;//秒数
	QString durationText = QString::number(min)+":"+QString::number(s);//durationlabel显示内容
	durationLabel->setMinimumSize(80,60);
	durationLabel->setMaximumSize(80,60);//固定大小,防止乱跑
	durationLabel->setText(durationText); //媒体总长度(分钟)
	durationLabel->setAlignment(Qt::AlignCenter | Qt::AlignHCenter);
	durationLabel->setStyleSheet("background-color:rgb(248,244,237);""color:rgb(20,145,168);");
	durationLabel->setWordWrap(true);//Label内容换行
}
//进度条实时变化
void MyMainWindow::videoPositionChanged(double position) //播放器进度信号的处理函数
{
	slider->setValue(position); //播放器进度改变时,更改滑动条上滑块的位置显示进度。
	int min = position/1000/60;//分钟
	int s = (position/1000/60 - min)*60;//秒数
	QString positionText = QString::number(min)+":"+QString::number(s);//进度label显示内容
	if(min == 0){
		positionText = QString::number(s);
	}
	timeLabel->setMinimumSize(80,60);
	timeLabel->setMaximumSize(80,60);//固定大小,防止乱跑
	timeLabel->setText(positionText); //当前播放进度
	timeLabel->setAlignment(Qt::AlignCenter | Qt::AlignHCenter);
	timeLabel->setStyleSheet("background-color:rgb(248,244,237);""color:rgb(20,145,168);");
	timeLabel->setWordWrap(true);//Label内容换行
}
//导入本地音乐
void MyMainWindow:: importLocalSongs(){
	QStringList filenames=QFileDialog::getOpenFileNames(this, "Open File", "","Music(*.mp3 *.flac *.ape);;All files (*.*)");
	for (int i=0; i<filenames.count(); i++){
		QFileInfo fileInfo(filenames.at(i));
		QString fileName = fileInfo.fileName();
		QListWidgetItem *item=new QListWidgetItem; //定义列表项
		item->setIcon(QPixmap("MultiMedia 32p-3.ico")); //设置列表项图标
		item->setText(fileName);//设置显示文本,比如显示歌名
		item->setData(Qt::UserRole, filenames.at(i));
		listWidget->addItem(item);//添加列表项到列表框
	}
	hLayout->addWidget(slider);
}
//歌曲列表双击操作
void MyMainWindow::listWidgetItemActivated(QListWidgetItem *activatedItem)
{
	for (int i=0; i<listWidget->count(); i++)//遍历列表框的所有项,设置背景色和前景色,更改图标
	{
		listWidget->item(i)->setForeground(QColor(0, 0, 0));
		listWidget->item(i)->setBackground(QColor(255, 255, 255));	
		listWidget->item(i)->setIcon(QPixmap("MultiMedia 32p-3.ico"));
	}
	playNow = listWidget->currentRow();
	activatedItem->setForeground(QColor(255, 0, 0)); 
	activatedItem->setBackground(QColor(0, 255, 0));
	activatedItem->setIcon(QPixmap("play2.png"));
	QString musicFullName = activatedItem->data(Qt::UserRole).toString(); //获得用户数据,也就是因为文件全名,可以送到播放器播放
	player->setMedia(QUrl::fromLocalFile(musicFullName));//设置播放器的媒体文件
	player->play();//开始播放
	QFileInfo fileInfo(musicFullName); //创建文件信息类对象fileInfo
	QString fileName=fileInfo.fileName(); //从fileInfo中获得文件名(无路径)
	songName->setText(fileName);
	QPixmap startIcon(tr("play2.png"));
    startButton->setIcon(startIcon);
	flag = 1;
	hLayout->addWidget(timeLabel);
	hLayout->addWidget(slider);
	hLayout->addWidget(durationLabel);
}
//打开音乐
void MyMainWindow:: openMusic()
{
	//打开文件选择对话框,过滤器选择mp3,flac,ape音乐文件,或者所有文件。
	QString fileFullName = QFileDialog::getOpenFileName(this, "Open Music", "","Music(*.mp3 *.flac *.ape);;All files (*.*)");
	if (fileFullName=="") return;//如果没有选择,返回。
	player->setMedia(QUrl::fromLocalFile(fileFullName));//设置播放器的媒体文件
	QPixmap startIcon(tr("play2.png"));
	startButton->setIcon(startIcon);//按钮设置成开始的样子
	player->play();//开始播放
	
	QFileInfo fileInfo(fileFullName); //创建文件信息类对象fileInfo
	QString fileName=fileInfo.fileName(); //从fileInfo中获得文件名(无路径)
	for (int i=0; i<listWidget->count(); i++)//遍历列表框的所有项,设置背景色和前景色,更改图标
	{
		listWidget->item(i)->setForeground(QColor(0, 0, 0));
		listWidget->item(i)->setBackground(QColor(255, 255, 255));	
		listWidget->item(i)->setIcon(QPixmap("MultiMedia 32p-3.ico"));
	}
	QListWidgetItem *item=new QListWidgetItem; //定义列表项
	item->setForeground(QColor(255, 0, 0)); 
	item->setBackground(QColor(0, 255, 0));
	item->setIcon(QPixmap("play2.png"));
	item->setText(fileName);//设置显示文本,比如显示歌名
	item->setData(Qt::UserRole, fileFullName);
	listWidget->addItem(item);//添加列表项到列表框
	songName->setText(fileName);
	playNow = listWidget->count() - 1;
}
//上一曲
void MyMainWindow:: lastMusic(){
	//上一曲,首位置,转回最后,其他的减减
	if(playNow == 0){
		playNow =listWidget->count()-1;
	}
	else{
		playNow--;
	}
	QString musicFullName = listWidget->item(playNow)->data(Qt::UserRole).toString(); //获得用户数据,也就是因为文件全名,可以送到播放器播放
	player->setMedia(QUrl::fromLocalFile(musicFullName));//设置播放器的媒体文件
	player->play();//开始播放
	//列表显示同步
	changeList();//调用changeList函数
}

//下一曲
void MyMainWindow:: nextMusic(){
	//下一曲1.末尾,转回第一曲2.不是末尾,加加
	if(playNow == listWidget->count()-1){
		playNow = 0;
	}
	else{
		playNow++;
	}
	QString musicFullName = listWidget->item(playNow)->data(Qt::UserRole).toString(); //获得用户数据,也就是因为文件全名,可以送到播放器播放
	player->setMedia(QUrl::fromLocalFile(musicFullName));//设置播放器的媒体文件
	player->play();//开始播放
	//列表显示同步
	changeList();//调用changeList函数
}
//播放模式改变,仅改变值,播放让状态函数变化
void MyMainWindow::changeMode(){

		if (Mode == 1)
		{
			Mode++;
			playMode->setIcon(QPixmap("Loop.png"));
		}
		else if(Mode == 2)
		{
			Mode++;
			playMode->setIcon(QPixmap("Random.png"));
		}
		else{
			Mode = 1;
			playMode->setIcon(QPixmap("Sequential.png"));
		}
}
//提示信息
void MyMainWindow::inputInformation()
{
	
}
//利用自带的函数来做1.顺序直接用nextMusic,2.循环不改变playNow3.随机,palyNow取1-list.count的随机数
void MyMainWindow:: mediaStatusChanged(QMediaPlayer::MediaStatus status)
{
	if (status == QMediaPlayer::InvalidMedia)   //无法播放媒体文件,输出错误信息
	{
		inputInformation();
	}
	else if (status == QMediaPlayer::EndOfMedia) //当前文件播放结束,播放下一首?
	{
		if (Mode == 1){
			nextMusic();
		}
		else if(Mode == 2){
			QString musicFullName = listWidget->item(playNow)->data(Qt::UserRole).toString(); //获得用户数据,也就是因为文件全名,可以送到播放器播放
			player->setMedia(QUrl::fromLocalFile(musicFullName));//设置播放器的媒体文件
			player->play();//开始播放
			//列表显示同步
			changeList();//调用changeList函数
		}
		else{
			playNow = generateRandomNumber();
			QString musicFullName = listWidget->item(playNow)->data(Qt::UserRole).toString(); //获得用户数据,也就是因为文件全名,可以送到播放器播放
			player->setMedia(QUrl::fromLocalFile(musicFullName));//设置播放器的媒体文件
			player->play();//开始播放
			//列表显示同步
			changeList();//调用changeList函数
		}
	}
}
//随机数产生
int MyMainWindow:: generateRandomNumber()
{
	int playRandom;
    QRandomGenerator(QTime(0,0,0).secsTo(QTime::currentTime()));
    do{
	playRandom =qrand()%listWidget->count();   	
	}
	while(playNow == playRandom); 	
    return playRandom;
}
void MyMainWindow::sliderPressedEvent()
{
	disconnect(player, &QMediaPlayer::positionChanged, this, &videoPositionChanged);
}
void MyMainWindow::startButtonEvent()
{
	if(flag == 0){
		player->play();//开始播放
		QPixmap startIcon(tr("play2.png"));
    	startButton->setIcon(startIcon);
		flag = 1;
	}
	else if(flag == 1){
		player->pause();//暂停播放
		QPixmap pauseIcon(tr("play4.png"));
    	startButton->setIcon(pauseIcon);
    	flag = 0;
	}
}
void MyMainWindow::sliderReleasedEvent()
{
	player->setPosition(slider->value());
	connect(player, &QMediaPlayer::positionChanged, this, &videoPositionChanged);
}

void MyMainWindow::sliderMovedEvent()
{
	timeLabel->setText(QString::number(slider->value()/1000/60)); //显示调整进度(分钟)
}

void MyMainWindow:: openFile()
{
	//打开文件选择对话框,过滤器选择mp4,mkv,avi等视频文件
	QString fileFullName = QFileDialog::getOpenFileName(this, "Open File", "","Videos(*.mp4 *.mkv *.avi *.wmv *.mov *.mpg *.rm *.rmvb);;All files (*.*)");
	if (fileFullName=="") return;//如果没有选择文件,返回。
	player->setMedia(QUrl::fromLocalFile(fileFullName));//设置播放器的媒体文件
	player->play();//开始播放
	view->fitInView(view->videoItem, Qt::KeepAspectRatio); //将视频项保持纵横比缩放到和视图窗口一样大小。
}

int main(int argc, char *argv[])
{
	QApplication app(argc, argv); 
	MyMainWindow mainWindow; 
	mainWindow.show();
	mainWindow.setGeometry(40,40,1800,1000);//位置
	//程序启动时接收的参数字符串列表,中文也自动转换为Unicode格式
	QStringList args = QApplication::arguments(); 
	int argsSize = args.size();//获得列表中的字符串个数
	if (argsSize>1) //args[0]是程序名,如果字符串个数超过1,表示main函数有参数输入
	{
		mainWindow.player->setMedia(QUrl::fromLocalFile(args[1]));//将args[1]参数设置为媒体源
		mainWindow.player->play();//调用mainWindow窗口中的公用成员player播放媒体文件
		mainWindow.songName->setText(args[1]);//将args[1]设置为主窗口公用成员label的显示文本
	}
	return app.exec(); 
}

2.file按钮打开文件

QMenu *fileMenu=new QMenu("File"); 
	//为fileMen添加一个菜单项,有图标和点击时的处理函数openFile();
	fileMenu->addAction(QPixmap("open.png"), "OpenVideo", this, &openFile); 
	fileMenu->addAction(QPixmap("open.png"), "OpenMusic", this, &openMusic); 
	menuBar->addMenu(fileMenu); //将fileMenu菜单添加到菜单栏

将按钮与函数做一个connect,实际上这里打开文件管理器是通过QFileDialog::getOpenFileName实现的,而不是直接与menu联系起来的。

void MyMainWindow:: openMusic()
{
	//打开文件选择对话框,过滤器选择mp3,flac,ape音乐文件,或者所有文件。
	QString fileFullName = QFileDialog::getOpenFileName(this, "Open Music", "","Music(*.mp3 *.flac *.ape);;All files (*.*)");
	

3. listWidget详解

listWidget是一个列表窗口,实例化后是一个自成体系的组件,主要由list->item构成内部,各种操作也是通过对item的操作来进行的。
在播放器中主要
1.list图标和背景改变以达到歌曲切换的效果

	for (int i=0; i<listWidget->count(); i++)//遍历列表框的所有项,设置背景色和前景色,更改图标
	{
		listWidget->item(i)->setForeground(QColor(0, 0, 0));
		listWidget->item(i)->setBackground(QColor(255, 255, 255));	
		listWidget->item(i)->setIcon(QPixmap("MultiMedia 32p-3.ico"));
	}

先把所有的列表都都变统一

	QListWidgetItem *item=new QListWidgetItem; //定义列表项
	item->setForeground(QColor(255, 0, 0)); 
	item->setBackground(QColor(0, 255, 0));
	item->setIcon(QPixmap("play2.png"));
	item->setText(fileName);//设置显示文本,比如显示歌名
	item->setData(Qt::UserRole, fileFullName);

再把正在播放的那个变成独特的

2.list双击,这个在下面详细说

4.slider控制音乐播放进度

这个很简单,slider组件是自动检测正在播放的音频文件的,都不用你多做,系统自动带着的功能

//滑动条最大值
void MyMainWindow::durationChanged(double duration) 
{
	slider->setMaximum(duration); //设置滑动条最大值
}
//进度条实时变化
void MyMainWindow::videoPositionChanged(double position) //播放器进度信号的处理函数
{
	slider->setValue(position); //播放器进度改变时,更改滑动条上滑块的位置显示进度。
}

5.多选文件添加到listWidget中

这个也很简单,QStringList filenames=QFileDialog::getOpenFileNames(this, “Open File”, “”,"Music(.mp3 .flac .ape);;All files (.)");*
打开文件时,按ctrl键来多选文件

QStringList filenames=QFileDialog::getOpenFileNames(this, "Open File", "","Music(*.mp3 *.flac *.ape);;All files (*.*)");
	for (int i=0; i<filenames.count(); i++){
		QFileInfo fileInfo(filenames.at(i));
		QString fileName = fileInfo.fileName();
		QListWidgetItem *item=new QListWidgetItem; //定义列表项
		item->setIcon(QPixmap("MultiMedia 32p-3.ico")); //设置列表项图标
		item->setText(fileName);//设置显示文本,比如显示歌名
		item->setData(Qt::UserRole, filenames.at(i));
		listWidget->addItem(item);//添加列表项到列表框
	}

6.播放暂停按钮

非常巧妙,一个键控制播放暂停,一看就懂
就是设置一个标志变量:flag,按下暂停按钮置为0,按下开始按钮置为1,其实这里只有一个按钮,两个不同是icon设置不同而已。

//播放暂停
void MyMainWindow::startButtonEvent()
{
	if(flag == 0){
		player->play();//开始播放
		QPixmap startIcon(tr("play2.png"));
    	startButton->setIcon(startIcon);
		flag = 1;
	}
	else if(flag == 1){
		player->pause();//暂停播放
		QPixmap pauseIcon(tr("play4.png"));
    	startButton->setIcon(pauseIcon);
    	flag = 0;
	}
}

7.进度显示,怎么转换成 分:秒的形式

也很简单,slider默认的是内存字节大小,先除以1000,换成60进制的。
QString::number(),数字转字符串

//滑动条最大值
void MyMainWindow::durationChanged(double duration) 
{
	slider->setMaximum(duration); //设置滑动条最大值
	int min = duration/1000/60;//分钟
	int s = (duration/1000/60 - min)*60;//秒数
	QString durationText = QString::number(min)+":"+QString::number(s);//durationlabel显示内容
	durationLabel->setText(durationText); //媒体总长度(分钟)
	durationLabel->setAlignment(Qt::AlignCenter | Qt::AlignHCenter);
	durationLabel->setStyleSheet("background-color:rgb(248,244,237);""color:rgb(20,145,168);");
	durationLabel->setWordWrap(true);//Label内容换行
}
//进度条实时变化
void MyMainWindow::videoPositionChanged(double position) //播放器进度信号的处理函数
{
	slider->setValue(position); //播放器进度改变时,更改滑动条上滑块的位置显示进度。
	int min = position/1000/60;//分钟
	int s = (position/1000/60 - min)*60;//秒数
	QString positionText = QString::number(min)+":"+QString::number(s);//进度label显示内容
	if(min == 0){
		positionText = QString::number(s);
	}
	timeLabel->setText(positionText); //当前播放进度
	timeLabel->setAlignment(Qt::AlignCenter | Qt::AlignHCenter);
	timeLabel->setStyleSheet("background-color:rgb(248,244,237);""color:rgb(20,145,168);");
	timeLabel->setWordWrap(true);//Label内容换行
}

8.双击歌曲名播放音乐

这个利用的是listWidget的自动传参功能,双击传给函数一个参数:被双击的这个item,然后进行操作,怎么实现播放呢。
1.要保证几种途径添加到列表的歌曲setData要有,也就是要知道文件的地址。
2.双击后,传递item的同时,传递了item的data
3.将item的data设置成播放的源。

void MyMainWindow::listWidgetItemActivated(QListWidgetItem *activatedItem)
{
	
	QString musicFullName = activatedItem->data(Qt::UserRole).toString(); //获得用户数据,也就是因为文件全名,可以送到播放器播放
	player->setMedia(QUrl::fromLocalFile(musicFullName));//设置播放器的媒体文件
	player->play();//开始播放
	QFileInfo fileInfo(musicFullName); //创建文件信息类对象fileInfo
	QString fileName=fileInfo.fileName(); //从fileInfo中获得文件名(无路径)
}

9.上一曲、下一曲

上一曲和下一曲功能的实现核心是知道现在播放的位置
因为我们这个软件播放的实现有两种情况
1.通过file这个menu打开文件播放,这种情况是添加在list末尾,所以palyNow的值是list.count().
2.双击播放,这时候playNow的值是 activateItem.At(n).
这样就好办了,上一曲和下一曲不过是将播放器的播放源设置成list(playNow+/-1).data即可
其中注意的是,首尾;两个位置需要置首或回到末尾。

10.playMode播放模式切换

这个类比播放暂停,也是一个按钮三个功能,1、2、3数字的变化对应三种下一曲的playNow的取值
其中比较麻烦的是随机模式,随机数的取法在qt下比较麻烦

 QRandomGenerator(QTime(0,0,0).secsTo(QTime::currentTime()));

实现的种子的改变,随着时间变化而变化,否则这个种子不变会产生相同的随机数
do while的好处是可以先得到一个判断值,如果先判断的话就得先确定一个值。
在这里do while,先do出来一个随机数,这样while就好添加判断条件了。
如果用while的话,不知道怎么写。

//随机数产生
int MyMainWindow:: generateRandomNumber()
{
	int playRandom;
    QRandomGenerator(QTime(0,0,0).secsTo(QTime::currentTime()));
    do{
	playRandom =qrand()%listWidget->count();   	
	}
	while(playNow == playRandom); 	
    return playRandom;
}

得到随机数随机模式也好办了

//播放模式改变,仅改变值,播放让状态函数变化
void MyMainWindow::changeMode(){

		if (Mode == 1)
		{
			Mode++;
			playMode->setIcon(QPixmap("Loop.png"));
		}
		else if(Mode == 2)
		{
			Mode++;
			playMode->setIcon(QPixmap("Random.png"));
		}
		else{
			Mode = 1;
			playMode->setIcon(QPixmap("Sequential.png"));
		}
}

前面这个函数只负责控制按钮的样子,以及给出mode编号1,2,3,他们在按钮按下时的改变关系。

//利用自带的函数来做1.顺序直接用nextMusic,2.循环不改变playNow3.随机,palyNow取1-list.count的随机数
void MyMainWindow:: mediaStatusChanged(QMediaPlayer::MediaStatus status)
{
	if (status == QMediaPlayer::InvalidMedia)   //无法播放媒体文件,输出错误信息
	{
		inputInformation();
	}
	else if (status == QMediaPlayer::EndOfMedia) //当前文件播放结束,播放下一首?
	{
		if (Mode == 1){
			nextMusic();
		}
		else if(Mode == 2){
			QString musicFullName = listWidget->item(playNow)->data(Qt::UserRole).toString(); //获得用户数据,也就是因为文件全名,可以送到播放器播放
			player->setMedia(QUrl::fromLocalFile(musicFullName));//设置播放器的媒体文件
			player->play();//开始播放
			//列表显示同步
			changeList();//调用changeList函数
		}
		else{
			playNow = generateRandomNumber();
			QString musicFullName = listWidget->item(playNow)->data(Qt::UserRole).toString(); //获得用户数据,也就是因为文件全名,可以送到播放器播放
			player->setMedia(QUrl::fromLocalFile(musicFullName));//设置播放器的媒体文件
			player->play();//开始播放
			//列表显示同步
			changeList();//调用changeList函数
		}
	}
}

这里很关键的一个:

void MyMainWindow:: mediaStatusChanged(QMediaPlayer::MediaStatus status)
{
	if (status == QMediaPlayer::InvalidMedia)   //无法播放媒体文件,输出错误信息
	{
		inputInformation();
	}
	else if (status == QMediaPlayer::EndOfMedia) //当前文件播放结束,播放下一首?
	{
	}
}

这个和slider一样,自动检测你的文件播放状态,我们的播放模式是在下一曲切换歌曲的时候起作用的,这里也是,结合这个做到播放模式变换的功能。
顺序播放:直接nextMusic函数
随机播放:把随机数传递过去,作为playNow。
循环,每次都playNow

11.main函数传参实现打开方式的选择

int main(int argc, char *argv[])
{
	QApplication app(argc, argv); 
MyMainWindow mainWindow; 
	mainWindow.show();
	mainWindow.setGeometry(40,40,1800,1000);//位置
	//程序启动时接收的参数字符串列表,中文也自动转换为Unicode格式
	QStringList args = QApplication::arguments(); 
	int argsSize = args.size();//获得列表中的字符串个数
	if (argsSize>1) //args[0]是程序名,如果字符串个数超过1,表示main函数有参数输入
	{
		mainWindow.show();
		mainWindow.setGeometry(40,40,1800,1000);//位置
		mainWindow.player->setMedia(QUrl::fromLocalFile(args[1]));//将args[1]参数设置为媒体源
		mainWindow.songName->setText(args[1]);//将args[1]设置为主窗口公用成员label的显示文本
		//打开文件选择对话框,过滤器选择mp3,flac,ape音乐文件,或者所有文件。
		mainWindow.startButton->setIcon(QPixmap ("play2.png"));//按钮设置成开始的样子
		mainWindow.player->play();//开始播放
	
		QFileInfo fileInfo(args[1]); //创建文件信息类对象fileInfo
		QString fileName=fileInfo.fileName(); //从fileInfo中获得文件名(无路径)
		for (int i=0; i<mainWindow.listWidget->count(); i++)//遍历列表框的所有项,设置背景色和前景色,更改图标
		{
			mainWindow.listWidget->item(i)->setForeground(QColor(0, 0, 0));
			mainWindow.listWidget->item(i)->setBackground(QColor(255, 255, 255));	
			mainWindow.listWidget->item(i)->setIcon(QPixmap("MultiMedia 32p-3.ico"));
		}
		QListWidgetItem *item=new QListWidgetItem; //定义列表项
		item->setForeground(QColor(255, 0, 0)); 
		item->setBackground(QColor(0, 255, 0));
		item->setIcon(QPixmap("play2.png"));
		item->setText(fileName);//设置显示文本,比如显示歌名
		item->setData(Qt::UserRole, QUrl::fromLocalFile(args[1]));
		mainWindow.listWidget->addItem(item);//添加列表项到列表框
		mainWindow.songName->setText(fileName);
		mainWindow.playNow = mainWindow.listWidget->count() - 1;
		}
	return app.exec(); 
}

就是打开方式应该是操作系统传一个参数args【1】过来,这个参数里是文件地址,然后在main函数里对这个文件全名处理就可以了。

细节 1. 去掉控制台

编译器选项添加指令-mwindow

细节 2. exe版本发布

qt发布exe多简单啊
CPP和EXE文件单独放一个目录下,然后打开CPP文件,在dev c++界面上点击Tools菜单,然后选择prompt command,打开一个黑方框窗口,在此窗口下输入Windeployqt LiBinMusic.exe就可以产生安装所需文件包。

细节3.LAV audio解码器

不然播放不了flac等文件,只能播放mp3
http://codecguide.com/download_kl.htm
大家到以上网站下载音视频解码器,安装过程中针对各种选项全部回车即可。


总结

本文仅仅简单介绍了简易播放器的制作,算是qt一个入门级的小项目吧。希望之后还能开发更多有趣的app

你可能感兴趣的:(qt开发,qt,c++,音视频)