基于Qt Phonon模块实现音乐播放器
这次使用Qt实现的是一个本地音乐播放器,可以播放下载在计算机本地的音乐,提供了添加歌曲,歌曲列表,清空列表的功能。默认歌曲列表循环播放。音乐播放的实现主要依赖的是Qt 的多媒体框架phonon。该音乐播放器的开发环境是Qt4.8.5+Qtcreator2.8.0。
音乐播放器界面如下:
主界面
歌曲列表
一、使用Qt Phonon框架播放音乐
想要写一个音乐播放器,最基本的当然就是要知道使用这个框架来播放音乐以及一些基本的播放控制比如暂停、停止、下一首等。只有知道了这些基本的东西,后面才可以将界面的按钮映射到实际的音乐播放代码中,实现播放器的功能。
在Qt4版本中,可以通过Phonon模块播放音乐。Phonon是一个跨平台的多媒体框架。但是,Phonon严格来说并不是Qt的库。Phonon原本就是KDE 4的开放原始码多媒体API,后来与Qt合并与开发。所以在Qt4.8.5中,我们可以使用该模块播放媒体音乐。(Qt5中似乎将该模块移除了,并用新的模块代替)。
使用Phonon模块来播放音乐的基本实现代码如下,当播放音频时,需要创建一个媒体对象,然后将它连接到一个音频输出节点,该节点由AudioOutput类提供,用来将音频输出到声卡。
Phonon::MediaObject *music;//声明媒体对象 Phonon::AudioOutput *audioout; Phonon::Path path; music=new Phonon::MediaObject; music->setCurrentSource(Phonon::MediaSource(songAddr));//songAddr是QString类型变量 audioout=new Phonon::AudioOutput(Phonon::MusicCategory,this); path=Phonon::createPath(music,audioout); music->play();//播放 music->pause();//暂停,再次调用play()时将接着暂停点接着播放 music->stop();//停止,再次调用play()函数时将从头播放 Phonon::SeekSlider *slider;//声明进度条 slider=new Phonon::SeekSlider;//将进度条与媒体对象连接 slider->setMediaObject(music);//将进度条与媒体对象连接 Phonon::VolumeSlider *voiceSlider=new Phonon::VolumeSlider; voiceSlider->setAudioOutput(audioout);//将音量控件与音频设备连接
二、界面设计——布局管理器和无边框窗口
为了界面的美化、将Qt窗口默认的边框去掉了,这样可以自由的对窗口进行美化(外面不会再有一个难看的框框影响美观^_^)。但是,去掉边框带来的后果是,没法拖动窗口。当然,这个最后可以通过重写相关的函数解决。
界面的布局主要如下图所示。实现这样的布局,当然是通过布局管理器。Qt提供了水平布局管理器和垂直布局管理器,整个播放器就是使用这两个布局管理器来布局的。灵活的使用这两个布局管理器可以很快的构建出一个排放整齐的界面。当然,要注意,一个窗口只能有一个主要的布局管理器。但是,我们可以通过布局管理器的“嵌套”来实现自定义的布局管理器。在Qt中,一个布局管理器中可以放入多个控件或者放入布局管理器或者混合放入(既有布局管理器又有控件)。下图便是通过这样的方法实现的。
三、无边框窗口的拖动
前面说过,去掉边框将导致没法拖动窗口,因为这时我们没法点击标题栏。所以,我们需要重写QWidget的mousePressEvent函数和mouseMoveEvent函数来实现无边框窗口的拖动。
void PlayerUI::mousePressEvent(QMouseEvent *event) {
/*在这里还可以添加鼠标点击的范围,在鼠标点击顶部某一部分的区域时可以拖动窗口,点击其他地方没法拖动*/ if(event->button()==Qt::LeftButton){ dragPosition=event->globalPos()-frameGeometry().topLeft(); event->accept(); } if(event->button()==Qt::RightButton){ return ; } } void PlayerUI::mouseMoveEvent(QMouseEvent *event) { if(event->buttons()==Qt::LeftButton){ move(event->globalPos()-dragPosition); event->accept(); } }
四、控件美化
Qt是一款基于C++的图形界面框架,它提供了基本的界面类,我们可以用这个界面类来编写自己的GUI程序。但是,Qt提供的都是一些最基本的框架,美观上自然达不到我们的要求。我们自然要对控件进行美化。
对于最下面的播放/暂停按钮,上一首、下一首按钮,通过设置按钮透明,再插入图片来实现美化,可以达到挺好的美化效果,但是在设置进度条时使用setstylesheet()来设置会比较好。进度条的效果如下图。【QSlider的样式设置可以参考这篇博客,里面有完整的代码。[传送门]】
Phonon::SeekSlider *slider; slider=new Phonon::SeekSlider; slider->setStyleSheet("QSlider::groove:horizontal{border: 1px solid #165708;background: #8f8f8f;height: 3px;border-radius: 2px;padding-left:-1px;padding-right:-1px;}QSlider::handle:horizontal{border:2px solid #454343;background:#2af5b9;width:9px;margin-top: -4px;margin-bottom: -4px;border-radius: 4px;} QSlider::sub-page:horizontal {background:#2af5b9;border: 1px solid #4A708B;height: 10px;border-radius: 2px;}QSlider::add-page:horizontal {background: #615f5f;border: 0px solid #2af5b9;height: 10px;border-radius: 2px;}");
需要注意的是,在进行样式设置时,要在一个setStylesheet()函数中写完,而不要分开写,不然可能会看不到效果。另外,如果设置的参数中出现矛盾的,也可能会使样式不起作用。
音量控制条的样式也是参考上面的代码的。他们的实现方法一样:
voiceSlider=new Phonon::VolumeSlider; voiceSlider->setStyleSheet("QSlider::groove:vertical{border: 1px solid #454343;background:qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 #3c3a3a,stop:1 #d6d3d3);;height:130px;width:3px;border-radius: 2px;padding-top:-1px;padding-bottom:-1px;}QSlider::handle:vertical{border:1px solid #454343;background:#2af5b9;height:11px;margin-left: -4px;margin-right: -4px;border-radius: 4px;}");
五、使用QTabelWidget实现歌曲播放列表
在歌曲列表的实现上,主要是使用QTableWidget类。QTableWidget的使用可参考网上教程【传送门】。
我在歌曲列表的实现上,只保留了一列,用来显示歌名,然后再使用样式表设置来实现一定的美化,去掉了边框、表头边框等。
六、小收获、小总结
最初,在Qt吧中看到有个大神完成了音乐播放器的程序并且发帖送出了源码。当时就佩服得五体投地。后来,就萌生了自己写个音乐播放器的想法。
这个播放器可以说是我第一个具有完整功能的程序。在整个程序的实现过程中,也遇到了很多困难,因为Qt中的很多控件我还是没有用过的,所以在写的过程中,不断的百度、谷歌以及查看内置的开发文档。不断的写代码测试,测试这样写实现的效果是什么、是否可以实现预期的功能、如何处理播放逻辑等等。就是在这样的过程中,代码从0开始,一行行积累起来,最终实现了这个播放器。
在整个过程中,不得不说还是收获了很多。最基本的,我对Qt的了解又多了一些,对Qt的使用更加的熟悉。也许Qt不能给我带来什么,但是,我很享受这个学习的过程,很享受自己从零开始实现某件事情的过程,它给我带来巨大的成就感。另外,在写代码的过程中,也发现了自己代码不规范的问题,包括命名到程序结构,不得不说,好烂。我自己都有这样的感觉。所以啊,还要继续努力呀。在以后的编程过程中,要从命名、结构等考虑自己写的东西,逐渐养成良好的编程好习惯。