QT5:C++实现基于multimedia的音乐播放器(一)
上一篇里简略的描述了一下播放器的实现,这一篇开始具体描述一下过程。
环境配置:Qt Creator
打开Qt Creator,创建一个new project,项目名称随你喜欢(我的是MusicPlayer),类名也随你喜欢(我的是Music),基类选择QWidget,不勾选界面UI(你也可以勾选UI,用QT自带的UI设计来创建界面),然后要记住项目保存路径不能有中文。
创建成功后,在MusicPlayer.pro(项目名称.pro)里加上“QT += multimedia”这一句:
1 QT += core gui 2 QT += multimedia 3 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
然后在头文件music.h(类名.h)里添加要用到的头文件名:
1 #include <QWidget> 2 #include <QMediaPlayer> 3 #include <QPushButton> 4 #include <QSlider> 5 #include <QLabel> 6 #include <QTime> 7 #include <QPaintEvent> 8 #include <QMediaPlaylist> 9 #include <QTimer> 10 #include <QListWidget>
并且在music类里写上要用到的对象成员和函数:
1 class Music : public QWidget 2 { 3 Q_OBJECT 4 public: 5 explicit Music(QWidget *parent = 0); 6 static int z; 7 8 public slots: 9 void addMoremusic(); 10 void playMusic(); 11 void preMusic(); 12 void nextMusic(); 13 void meteOpen(); 14 void volumChange(int); 15 void positionChange(qint64 position); 16 void showMessage(bool); 17 void seekChange(int position); 18 void posChange(); 19 void clearMessage(); 20 void musicPlayPattern(); 21 22 private: 23 void init_controls(); 24 void init_skin(); 25 26 QPushButton *BtnClose; 27 QPushButton *BtnMin; 28 QPushButton *BtnPlay; 29 QPushButton *BtnPrev; 30 QPushButton *BtnNext; 31 QPushButton *muteButton; 32 QPushButton *addMore; 33 QPushButton *playPattern; 34 QSlider *volumeControl; 35 QSlider *seekSlider; 36 QLabel *showTime; 37 QLabel *showPro; 38 QLabel *showMge; 39 QLabel *title; 40 QLabel *message; 41 QListWidget *list; 42 bool add; 43 QTimer *timer; 44 QTimer *timer2; 45 int moved; 46 QPoint dragPosition; 47 QMediaPlayer *player; 48 QMediaPlaylist * playList; 49 50 protected: 51 void paintEvent(QPaintEvent *event); 52 void mousePressEvent(QMouseEvent *event); 53 void mouseMoveEvent(QMouseEvent *event); 54 };
还要在源文件music.cpp里加上要用的头文件名:
1 #include "music.h" 2 #include <QPixmap> 3 #include <QFile> 4 #include <QPainter> 5 #include <QFileDialog> 6 #include <QUrl> 7 #include <QDebug> 8 #include <QMediaMetaData> 9 #include <QMessageBox> 10 #include <QFileInfo>
接着添加资源文件,把要用的图标和背景图片都添加到项目里,然后就可以在music.cpp里写播放器的界面了。
1 Music::Music(QWidget *parent) : QWidget(parent) 2 { 3 QPixmap background; 4 background.load(":/image/music_bg.bmp");//加载背景图片 5 this -> resize(background.width(),background.height());//设置窗口和背景图片大小一致 6 this -> setWindowFlags(Qt::FramelessWindowHint);//产生一个无窗口边框的窗口,用户无法改变它的大小也无法移动它 7 add = false; 8 moved = 0; 9 timer = new QTimer(this); 10 timer2 = new QTimer(this); 11 12 player = new QMediaPlayer(this);//QMediaplayer用于解析音频文件和视频文件 13 playList = new QMediaPlaylist; 14 15 init_controls();//创建按钮 16 init_skin();//外部加载qss文件,绘制界面样式 17 18 connect(player, SIGNAL(metaDataAvailableChanged(bool)), this, SLOT(showMessage(bool))); 19 connect(seekSlider,SIGNAL(sliderMoved(int)), this,SLOT(seekChange(int))); 20 }
因为我创建的是一个无法移动的窗体,所以重写鼠标左键函数来让它可以被移动,这样的话,鼠标左键按住时可以拖动窗体了:
//令窗口可以被拖动 void Music::mousePressEvent(QMouseEvent *event){ if(event->buttons()==Qt::LeftButton) { dragPosition=event->globalPos()-frameGeometry().topLeft(); event->accept(); } } void Music::mouseMoveEvent(QMouseEvent *event) { if(event->buttons() & Qt::LeftButton) { this ->move(event->globalPos() - dragPosition); event->accept(); } } //绘制背景 void Music::paintEvent(QPaintEvent *event) { QPainter paint(this); QPixmap backgound; backgound.load(":/image/music_bg.bmp"); paint.drawPixmap(0, 0, backgound.width(), backgound.height(),backgound); event ->accept(); }
然后写创建按钮的函数以及连接槽函数来响应信号的连接语句:
//创建按钮 void Music::init_controls() { BtnClose = new QPushButton(this); BtnClose -> setObjectName("BtnClose");//如果要对这个对象单独设stylesheet的话一定要设置它的objectName BtnClose -> setGeometry(365,2,30,30);//窗口左上角为原点(X365,Y2),(宽30,高30) BtnClose -> setToolTip(tr("退出")); BtnClose -> setCursor(QCursor(Qt::PointingHandCursor));//鼠标指针形状为手 BtnMin=new QPushButton(this); BtnMin->setObjectName(tr("BtnMin")); BtnMin->setGeometry(330,5,25,30); BtnMin->setToolTip(tr("最小化")); BtnMin->setCursor(QCursor(Qt::PointingHandCursor)); playPattern=new QPushButton(this); /*QIcon icon1(":/image/Seq.png"); playPattern->setIcon(icon1);*/ playPattern->setObjectName(tr("playPattern")); playPattern->setGeometry(20,255,50,50); playPattern->setToolTip(tr("列表循环")); playPattern->setCursor(QCursor(Qt::PointingHandCursor)); BtnPlay=new QPushButton(this); BtnPlay->setObjectName(tr("BtnPlay")); BtnPlay->setGeometry(160,250,56,56); BtnPlay->setToolTip(tr("播放")); BtnPlay->setCursor(QCursor(Qt::PointingHandCursor)); BtnPrev=new QPushButton(this); BtnPrev->setObjectName(tr("BtnPrev")); BtnPrev->setGeometry(120,255,45,45); BtnPrev->setToolTip(tr("上一首")); BtnPrev->setCursor(QCursor(Qt::PointingHandCursor)); BtnNext=new QPushButton(this); BtnNext->setObjectName(tr("BtnNext")); BtnNext->setGeometry(210,255,45,45); BtnNext->setToolTip(tr("下一首")); BtnNext->setCursor(QCursor(Qt::PointingHandCursor)); muteButton=new QPushButton(this); muteButton->setObjectName(tr("muteButton")); muteButton->setGeometry(370,320,25,25); muteButton->setToolTip(tr("关闭声音")); muteButton->setCursor(QCursor(Qt::PointingHandCursor)); volumeControl=new QSlider(Qt::Vertical,this);//QSlider(Qt::Vertical,this)创建一个竖直方向的滑动条QSlider控件 volumeControl->setObjectName(tr("volumeControl")); volumeControl->setGeometry(375,240,15,80); volumeControl->setCursor(QCursor(Qt::PointingHandCursor)); volumeControl->setRange(0,100);//设置滑动条控件的最小值和最大值 volumeControl ->setValue(50);//设置初值为50; seekSlider = new QSlider(Qt::Horizontal,this);//QSlider(Qt::Horizontal,this)创建一个水平方向的滑动条QSlider控件 seekSlider -> setGeometry(100,345,200,15); seekSlider->setObjectName(tr("seekSlider")); seekSlider -> setCursor(QCursor(Qt::PointingHandCursor)); addMore = new QPushButton(this); addMore -> setGeometry(295,2,30,30); addMore -> setObjectName(tr("addMore")); addMore->setToolTip(tr("添加歌曲")); addMore -> setCursor(QCursor(Qt::PointingHandCursor)); showMge = new QLabel(this); showMge -> setGeometry(34,320,400,20); showMge -> setFont(QFont("Times",10,QFont::Bold));//字体使用Times,10号字体,加粗 QPalette pac;//创建调色板 pac.setColor(QPalette::WindowText,QColor(70,80,70)); showMge -> setPalette(pac); list = new QListWidget(this); list ->setGeometry(20,50,360,180); list -> setFont(QFont("Times",10,QFont::Bold)); list -> setPalette(pac); list ->setStyleSheet("background: rgba(0,0,0,0.1);"); message = new QLabel(this); message -> setGeometry(20,30,140,20); message -> setFont(QFont("Times",10,QFont::Bold)); message -> setPalette(pac); showPro = new QLabel(this); showPro -> setGeometry(35,340,50,20); showPro -> setFont(QFont("Times",10,QFont::Bold)); showPro -> setPalette(pac); QTime mov(0,0,0); showPro ->setText(mov.toString("mm:ss")); showTime = new QLabel(this); showTime -> setGeometry(325,340,50,20); showTime -> setFont(QFont("Times",10,QFont::Bold)); showTime -> setPalette(pac); QTime mo(0,0,0);//QTime 提供时间函数给用户使用 showTime ->setText(mo.toString("mm:ss"));//显示分:秒 title = new QLabel(this);//设置标题 title -> setGeometry(5,0,200,30); title ->setFont(QFont("Times",15,QFont::Bold)); QPalette pa; pa.setColor(QPalette::WindowText,QColor(0,0,0)); title -> setPalette(pa); title -> setText("MusicPlayer"); //信号与槽 connect(BtnClose, SIGNAL(clicked(bool)), this, SLOT(close())); connect(BtnMin, SIGNAL(clicked(bool)), this, SLOT(showMinimized())); connect(addMore, SIGNAL(clicked(bool)), this, SLOT(addMoremusic())); connect(BtnPlay, SIGNAL(clicked(bool)), this, SLOT(playMusic())); connect (BtnPrev,SIGNAL(clicked(bool)), this, SLOT(preMusic())); connect(BtnNext, SIGNAL(clicked(bool)), this, SLOT(nextMusic())); connect(muteButton, SIGNAL(clicked(bool)), this, SLOT(meteOpen())); connect(volumeControl, SIGNAL(sliderMoved(int)), this, SLOT(volumChange(int))); connect(player,SIGNAL(positionChanged(qint64)),this,SLOT( positionChange(qint64))); connect(playPattern,SIGNAL(clicked(bool)),this,SLOT(musicPlayPattern())); }
但界面很丑,所以下一步就是加载qss文件,绘制界面样式:
1 //外部加载qss文件,绘制界面样式 2 void Music::init_skin() 3 { 4 QFile file(":/qss/skin.qss"); 5 file.open(QFile::ReadOnly); 6 this -> setStyleSheet(QObject::tr(file.readAll())); 7 file.close(); 8 9 }
我的qss代码如下(qss和css的语法几乎一模一样):
1 QPushButton#playPattern:!hover 2 { 3 border-image: url(:/image/Seq.png); 4 } 5 QPushButton#playPattern:hover 6 { 7 border-image: url(:/image/Seq.png); 8 } 9 QPushButton#playPattern:pressed{ 10 border-image: url(:/image/Seq.png); 11 } 12 QPushButton#BtnClose:!hover 13 { 14 border-image: url(:/image/close.png); 15 } 16 QPushButton#BtnClose:hover 17 { 18 border-image: url(:/image/close.png); 19 } 20 QPushButton#BtnClose:pressed 21 { 22 border-image: url(:/image/close.png); 23 } 24 QPushButton#BtnClose:focus{padding:-1;} 25 26 27 28 QPushButton#addMore 29 { 30 border-image: url(:/image/addMore.png); 31 32 } 33 34 35 QPushButton#BtnMin:!hover 36 { 37 border-image: url(:/image/min.png); 38 } 39 QPushButton#BtnMin:hover 40 { 41 border-image: url(:/image/min.png); 42 } 43 QPushButton#BtnMin:pressed 44 { 45 border-image: url(:/image/min.png); 46 } 47 QPushButton#BtnMin:focus{padding:-1;} 48 49 50 QPushButton#BtnPlay:!hover 51 { 52 border-image: url(:/image/play_hover.png); 53 } 54 QPushButton#BtnPlay:hover 55 { 56 border-image: url(:/image/play_hover.png); 57 } 58 QPushButton#BtnPlay:pressed 59 { 60 border-image: url(:/image/play_press.png); 61 } 62 QPushButton#BtnPlay:focus 63 { 64 padding:-1; 65 } 66 67 QPushButton#BtnPrev:!hover 68 { 69 border-image: url(:/image/prev_hover.png); 70 } 71 QPushButton#BtnPrev:hover 72 { 73 border-image: url(:/image/prev_hover.png); 74 } 75 QPushButton#BtnPrev:pressed 76 { 77 border-image: url(:/image/prev_press.png); 78 } 79 QPushButton#BtnPrev:focus{padding:-1;} 80 81 QPushButton#BtnNext:!hover 82 { 83 border-image: url(:/image/next_hover.png); 84 } 85 QPushButton#BtnNext:hover 86 { 87 border-image: url(:/image/next_hover.png); 88 } 89 QPushButton#BtnNext:pressed 90 { 91 border-image: url(:/image/next_press.png); 92 } 93 QPushButton#BtnNext:focus{padding:-1;} 94 95 96 QPushButton#muteButton:!hover 97 { 98 border-image: url(:/image/sound.png); 99 } 100 QPushButton#muteButton:hover 101 { 102 border-image: url(:/image/sound.png); 103 } 104 QPushButton#muteButton:pressed 105 { 106 border-image: url(:/image/sound_close.png); 107 } 108 QPushButton#muteButton:focus{padding:-1;} 109 110 111 112 QSlider#volumeControl::groove:Vertical { 113 border: 0px solid #bbb; 114 background: rgba(0,0,0,0.1); 115 width: 4px; 116 border-radius: 1px; 117 } 118 119 QSlider#volumeControl::sub-page:Vertical { 120 background: rgba(0,0,0,0.1); 121 border: 0px solid #777; 122 width: 4px; 123 border-radius: 1px; 124 } 125 126 QSlider#volumeControl::add-page:Vertical { 127 background:url(:/image/progress_sound.bmp); 128 border: 0px solid #777; 129 width: 4px; 130 border-radius: 1px; 131 } 132 133 QSlider#volumeControl::handle:Vertical { 134 border-image:url(:/image/progress_thume.png); 135 border: 0px solid #777; 136 width: 28px; 137 height: 28px; 138 margin-left:-12px; 139 margin-right:-12px; 140 margin-top: -12px; 141 margin-bottom: -12px; 142 border-radius: 4px; 143 } 144 145 146 QSlider#seekSlider::groove:horizontal { 147 border-left:-14px solid; 148 background: rgba(0,0,0,0.1); 149 height: 4px; 150 border-radius: 4px; 151 } 152 153 QSlider#seekSlider::sub-page:horizontal { 154 background:url(:/image/progress.bmp); 155 border: 0px solid #777; 156 height: 4px; 157 border-radius: 4px; 158 } 159 160 QSlider#seekSlider::add-page:horizontal { 161 background: rgba(0,0,0,0.1); 162 border: 0px solid #777; 163 height: 4px; 164 border-radius:4px; 165 } 166 167 QSlider#seekSlider::handle:horizontal { 168 background:url(:/image/progress_thume.png); 169 border: 0px solid #777; 170 width: 28px; 171 height: 28px; 172 border-left:0px; 173 border-right:0px; 174 margin-left:2px; 175 margin-right:-12px; 176 margin-top: -12px; 177 margin-bottom: -12px; 178 border-radius: 4px; 179 }
这样样式就已经基本搞定了,只剩下写槽函数来实现具体功能了。