欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

QT5:C++实现基于multimedia的音乐播放器(一)

程序员文章站 2022-07-25 14:53:30
上一篇里简略的描述了一下播放器的实现,这一篇开始具体描述一下过程。 环境配置:Qt Creator 打开Qt Creator,创建一个new project,项目名称随你喜欢(我的是MusicPlayer),类名也随你喜欢(我的是Music),基类选择QWidget,不勾选界面UI(你也可以勾选UI ......

上一篇里简略的描述了一下播放器的实现,这一篇开始具体描述一下过程。

环境配置: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类里写上要用到的对象成员和函数:

QT5:C++实现基于multimedia的音乐播放器(一)
 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 };
View Code

还要在源文件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)//event->buttons()==Qt::LeftButton && event ->y() < 50 && event ->x() < 330
    {
        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();

}

然后写创建按钮的函数以及连接槽函数来响应信号的连接语句:

QT5:C++实现基于multimedia的音乐播放器(一)
//创建按钮
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()));


}
View Code

但界面很丑,所以下一步就是加载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的语法几乎一模一样):

QT5:C++实现基于multimedia的音乐播放器(一)
  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 }
View Code

这样样式就已经基本搞定了,只剩下写槽函数来实现具体功能了。