QT5:C++实现基于multimedia的音乐播放器(一) - 郭佬 - 博客园

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 };
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)
    {
        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()));


}
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的语法几乎一模一样):

  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

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

posted @ 2018-04-23 23:06 郭佬 阅读(...) 评论(...) 编辑 收藏
我终究成长为一个不特别的人