嵌入式系統(tǒng)課程設(shè)計(jì)-音樂播放器_第1頁(yè)
嵌入式系統(tǒng)課程設(shè)計(jì)-音樂播放器_第2頁(yè)
嵌入式系統(tǒng)課程設(shè)計(jì)-音樂播放器_第3頁(yè)
嵌入式系統(tǒng)課程設(shè)計(jì)-音樂播放器_第4頁(yè)
嵌入式系統(tǒng)課程設(shè)計(jì)-音樂播放器_第5頁(yè)
已閱讀5頁(yè),還剩57頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

./課程設(shè)計(jì)說明書課程設(shè)計(jì)名稱:嵌入式系統(tǒng)課程設(shè)計(jì)課程設(shè)計(jì)題目:音樂播放器學(xué)院名稱:信息工程學(xué)院專業(yè):計(jì)算機(jī)科學(xué)與技術(shù)__090451__09045102__評(píng)分:教師:20xx11月30日.TOC\o"1-4"\h\u9904摘要:14234第一章課程設(shè)計(jì)要求和內(nèi)容28441.1設(shè)計(jì)目標(biāo)和要求2137031.2設(shè)計(jì)內(nèi)容227910第二章開發(fā)工具介紹321223第三章系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)4223633.1宿主機(jī)開發(fā)環(huán)境配置4220523.2功能分析與方案論證5271443.2.1功能分析580773.2.2可行性分析514373.3需求分析5289323.4詳細(xì)設(shè)計(jì)64433.4.1系統(tǒng)的功能模塊設(shè)計(jì)650613.4.2界面窗口模塊詳細(xì)設(shè)計(jì)與實(shí)現(xiàn)66724MP3文件播放控制模塊詳細(xì)設(shè)計(jì)與實(shí)現(xiàn)9300453.4.6主要程序文件〔代碼見附錄〕27397第四章調(diào)試分析1215656第五章設(shè)計(jì)總結(jié)125531主要參考文獻(xiàn):1310014附錄<流程圖、源代碼>:1419370附錄1相關(guān)流程圖145564附錄2系統(tǒng)運(yùn)行效果161946附錄3程序源代碼17音樂播放器摘要:隨著用戶要求的不斷提高,越來越多的嵌入式設(shè)備使用功能強(qiáng)大、價(jià)格低廉的嵌入式Linux作為操作系統(tǒng)并開始采用較為復(fù)雜的圖形用戶界面。Qt以其強(qiáng)大的功能、良好的可移植性逐漸成為一種被廣泛使用的GUI系統(tǒng)。正是由于嵌入式操作系統(tǒng)與其相應(yīng)圖形用戶界面的不斷發(fā)展,嵌入式軟件的開發(fā)顯得越來越重要,其中嵌入式媒體播放器由于能夠滿足人們的視聽享受已經(jīng)逐漸成為了系統(tǒng)中不可或缺的重要組成部分,在嵌入式系統(tǒng)上開發(fā)媒體播放器已經(jīng)成為了一個(gè)技術(shù)熱點(diǎn),當(dāng)前許多嵌入式產(chǎn)品中都包含媒體播放器。因此在基于Qt的嵌入式Linux系統(tǒng)中實(shí)現(xiàn)媒體播放器具有深刻的意義和實(shí)用價(jià)值。本次課程設(shè)計(jì)運(yùn)用Qt技術(shù)在Linux下進(jìn)行GUI設(shè)計(jì),以一個(gè)圖形界面為例,運(yùn)用QTcreator軟件編程,實(shí)現(xiàn)一個(gè)簡(jiǎn)單的音樂播放器。此播放器能夠播放本地的音頻文件,在功能方面,它具備一些基本的音樂操作處理功能,如暫停、播放、音量調(diào)節(jié)、停止等,此外,界面還能顯示歌曲信息,比如顯示播放列表,播放的時(shí)候能夠通過按鈕來實(shí)現(xiàn)歌詞顯示的功能。關(guān)鍵詞:嵌入式系統(tǒng)音樂播放器QTLinux第一章課程設(shè)計(jì)要求和內(nèi)容1.1設(shè)計(jì)目標(biāo)和要求掌握linux應(yīng)用開發(fā)的基本理論知識(shí)和基本方法技能,概念清楚明確,系統(tǒng)分析、系統(tǒng)設(shè)計(jì)、系統(tǒng)實(shí)現(xiàn)、系統(tǒng)測(cè)試符合軟件工程的相關(guān)規(guī)X,結(jié)構(gòu)合理,程序運(yùn)行良好。實(shí)現(xiàn)Linux系統(tǒng)下的音樂播放器設(shè)計(jì),實(shí)現(xiàn)一個(gè)播放Mp3格式音樂的嵌入式多媒體播放系統(tǒng)。具有良好的圖形用戶設(shè)計(jì)界面。1.2設(shè)計(jì)內(nèi)容運(yùn)用Qt技術(shù)在Linux下進(jìn)行GUI設(shè)計(jì),以一個(gè)圖形界面為例,運(yùn)用QTcreator軟件編程,實(shí)現(xiàn)一個(gè)簡(jiǎn)單的音樂播放器。此播放器能夠播放本地的音頻文件,在功能方面,它具備一些基本的音樂操作處理功能,如暫停、播放、音量調(diào)節(jié)、停止等,此外,界面還能顯示歌曲信息,比如顯示播放列表,播放的時(shí)候能夠通過按鈕來實(shí)現(xiàn)歌詞顯示的功能。第二章開發(fā)工具介紹Qt從4.4版本開始提供的一套多媒體框架,提供多媒體回放的功能。目前在Qt4.6中實(shí)現(xiàn)多媒體播放圖形界面主要依賴于phonon框架,其實(shí)qt中還有一個(gè)Multimedia模塊,幫助文檔中對(duì)它的描述是:實(shí)現(xiàn)底層的多媒體播放功能,在一般情況下上層的接口phonon模塊更適合實(shí)現(xiàn)這些功能。phonon最初是一個(gè)源于KDE的項(xiàng)目,為使用音頻和視頻的應(yīng)用程序開發(fā)提供的一個(gè)框架。應(yīng)用程序不用去管多媒體播放是通過什么實(shí)現(xiàn)的〔如gstreamer、xine〕,只需調(diào)用相應(yīng)的接口就行,但這中間需要一個(gè)中轉(zhuǎn),被稱為backend。Qt也是通過phonon來實(shí)現(xiàn)夸平臺(tái)的多媒體播放。多媒體文件的播放主要過程包括:文件讀取、分流、解碼、輸出。如圖1所示圖1多媒體文件的播放主要過程這些在不同的系統(tǒng)中實(shí)現(xiàn)方式不同,如windows下的DirectX、Linux下的gstreamer或xine與Mac下的QuickTime。而Qt中的phonon作為夸平臺(tái)的多媒體解決方案,就因該為用戶屏蔽掉這些差異。而實(shí)際上它做得還不夠好,因?yàn)橛脩暨€需要自己來安裝相應(yīng)的后端插件來完成播放任務(wù)。如圖2圖2Phonon庫(kù)的調(diào)用使用過程應(yīng)用Phonon框架實(shí)質(zhì)上分4個(gè)部分,你的程序,Phonon庫(kù),Phonon后端插件<phonon_backend>,真正的后端。Phonon其實(shí)什么都不干,他只是提供了一套API接口,這套接口可以給你的程序調(diào)用,同時(shí)也是給編寫后端插件提供一個(gè)規(guī)X。程序完全不知道最后誰來放我的Mp3,誰來解碼我的視頻,播放的又是哪個(gè)設(shè)備。同樣,Phonon庫(kù)也不知道,他只管搜索符合自己規(guī)X的插件。并告訴這些插件,現(xiàn)在程序發(fā)出的指令是什么,從插件返回給程序現(xiàn)在的媒體狀態(tài)和信息。而后端才是實(shí)際進(jìn)行讀入媒體、解碼并且播放的部分,他們和后端插件是一一對(duì)應(yīng)的。后端可以是任何形式,只要你寫出了相應(yīng)的后端插件。所以,使用Phonon必需要先做2件事:1、編譯Phonon庫(kù):通常情況下,Qt默認(rèn)沒有編譯,需要configure后加好參數(shù),然后單獨(dú)進(jìn)入phonon的文件夾進(jìn)行編譯就可以了2、編譯Phonon后端插件:Qt為3大平臺(tái)分別提供了一個(gè)可用的后端插件,放在src\plugins\phonon目錄下。進(jìn)入目錄編譯即可,Qt會(huì)自動(dòng)選擇你當(dāng)前系統(tǒng)的后端插件的。<出現(xiàn)phononbackendplugincouldnotbeloaded就是這步?jīng)]有做>.如果是MinGW用戶,Windows下Qt只提供了DirectShow這個(gè)后端插件,而這個(gè)后端插件因?yàn)檎{(diào)用了DX的SDK,所以只能由VC編譯。當(dāng)然其實(shí)有更好的選擇,比如這個(gè)phonon-vlc-mplayer插件,通過他,可以將mplayer作為后端,徹底拋棄臃腫的VS以與讀ID3v2都會(huì)出錯(cuò)的DirectShow,Phonon是KDE4的多媒體API。Phonon提供一個(gè)穩(wěn)定的API允許KDE4獨(dú)立于任何一個(gè)聲音系統(tǒng)服務(wù)器如xine。Phonon讓各種后端提供界面給開發(fā)者所謂的"引擎";每個(gè)引擎運(yùn)作在一個(gè)具體的后端。每個(gè)后端都可讓Phonon控制基本功能,如播放、暫停和搜尋。Phonon也支持更高層次的功能,如讓音軌轉(zhuǎn)化之間變微弱。使用Solid,Phonon將給予用戶更多配件的控制能力如耳機(jī)、揚(yáng)聲器、麥克風(fēng)。一個(gè)例子是,因?yàn)槟憧赡苤挥幸粋€(gè)VoIP會(huì)話使用您的耳機(jī),但所有其他的聲音通過揚(yáng)聲器出來。支援Unix-like系統(tǒng)下的后端xine、VLC、MPlayer。支援Windows下的后端DirectShow、VLC和MPlayer.支援MacOSX下的后端QuickTime。如上所述,如果想要運(yùn)行使用Qt中的phonon寫的程序,需要滿足一下條件:Qt基本庫(kù)、Qtphonon庫(kù)、phonon_backend<后端插件>和多媒體播放后臺(tái)。第三章系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)3.1宿主機(jī)開發(fā)環(huán)境配置安裝Linux系統(tǒng):宿主開發(fā)環(huán)境,我們選用在windows下安裝VMwareWorkStation虛擬機(jī)RedHatLinux5的組合來組建。在虛擬機(jī)中安裝Linux系統(tǒng):我們選擇標(biāo)準(zhǔn)安裝<Typical>安裝過程中先創(chuàng)建一個(gè)虛擬空白盤,然后選擇Linux系統(tǒng)版本為RedHatLinux5,整個(gè)安裝流程參照用戶手冊(cè)來完成。在Linux下安裝QTCreator:從QT官網(wǎng)上可以直接下載到QTCreator,下載完畢后,直接在終端運(yùn)行安裝包,選擇默認(rèn)安裝類型,即可完成QTCreator的安裝。3.2功能分析與方案論證3.2.1功能分析通過運(yùn)用Qt技術(shù)在嵌入式Linux操作系統(tǒng)下,進(jìn)行GUI設(shè)計(jì),以一個(gè)圖形界面為例,運(yùn)用QTcreator軟件編程,來完成音樂播放器的設(shè)計(jì)和實(shí)現(xiàn)音樂播放器的各種功能,使播放器能夠顯示播放列表,播放本地的音頻文件,通過點(diǎn)擊相應(yīng)的按鈕來實(shí)現(xiàn)歌曲的播放、暫停、停止等功能,此外,界面還能進(jìn)行音量調(diào)節(jié),顯示歌曲信息,比如顯示正在播放在音頻文件的時(shí)間信息,播放的時(shí)候能夠通過按鈕來實(shí)現(xiàn)播放列表和歌詞的顯示的功能。3.2.2可行性分析計(jì)算機(jī)技術(shù)的發(fā)展目前Linux已被廣泛應(yīng)用于信息家電、數(shù)據(jù)網(wǎng)絡(luò)、工業(yè)控制、醫(yī)療衛(wèi)生、航空航天等眾多領(lǐng)域。在嵌入式領(lǐng)域,由于價(jià)格低廉、結(jié)構(gòu)小巧的各種微處理器的出現(xiàn)為外設(shè)連接提供了穩(wěn)定可靠的硬件架構(gòu)限制嵌入式系統(tǒng)發(fā)展的瓶頸就突出表現(xiàn)在軟件方面。近年來隨著芯片技術(shù)的快速發(fā)展嵌入式系統(tǒng)的性能逐步提高,功能也越來越豐富。嵌入式系統(tǒng)在眾多領(lǐng)域的應(yīng)用給我們的生活帶來了便利并且對(duì)人們的生活方式的改變和生活質(zhì)量的提高具有重要的影響。在這些領(lǐng)域中,消費(fèi)電子產(chǎn)品的應(yīng)用具有更為廣泛的潛力,尤其是便攜式消費(fèi)電子產(chǎn)品。3.3需求分析程序設(shè)計(jì)目標(biāo):程序設(shè)計(jì)目標(biāo)是:結(jié)合QT技術(shù)和C++語(yǔ)言實(shí)現(xiàn)一個(gè)圖形界面mp3音頻播放器。具體目標(biāo)如下:1>能夠方便地選擇本機(jī)上的一個(gè)mp3文件進(jìn)行播放。選擇mp3文件時(shí),不需要有鍵盤輸入操作。2>播放過程中可以暫停,暫停后可以從暫停處再次播放。播放過程中可以停止,點(diǎn)擊播放按鈕后,可以再次從開頭播放本文件。3>播放、暫停、或停止?fàn)顟B(tài)中,都可以選擇其它mp3文件代替當(dāng)前mp3文件進(jìn)行播放。4>在面板上顯示mp3文件當(dāng)前播放的時(shí)間和mp3文件的名字。播放時(shí)間隨時(shí)刷新,配合好前面的播放調(diào)節(jié)操作。5>本程序中要有一個(gè)滾動(dòng)條來顯示當(dāng)前的mp3文件播放位置,拖動(dòng)滾動(dòng)條,可以調(diào)節(jié)mp3文件的播放位置。6>本程序中要有一個(gè)滑塊來顯示當(dāng)前的mp3音頻文件的播放音量,拖動(dòng)滑塊,可以調(diào)節(jié)音頻的播放音量。7〕點(diǎn)擊打開按鈕可以打開/關(guān)閉播放列表。8〕點(diǎn)擊歌詞按鈕可以顯示/關(guān)閉桌面歌詞。9>界面盡量美觀,程序運(yùn)行時(shí)不要出現(xiàn)異常。3.4詳細(xì)設(shè)計(jì)3.4.1系統(tǒng)的功能模塊設(shè)計(jì)一個(gè)軟件系統(tǒng)設(shè)計(jì)的成敗,除了在功能上要盡可能地完善以外,在界面設(shè)計(jì)上也有很大的決定性作用。如果你的軟件界面很糟糕,不能讓使用該軟件的用戶滿意,那么你開發(fā)的產(chǎn)品將被"凍結(jié)"起來,得不到用戶的響應(yīng)。所以,軟件產(chǎn)品的界面設(shè)計(jì)應(yīng)該具有友好性這一特點(diǎn)。除此之外,還應(yīng)該有簡(jiǎn)潔性。如果你的產(chǎn)品只注意了友好美觀的界面,而使得你的界面很復(fù)雜,將會(huì)給用戶帶來極大的不便,從而會(huì)適得其反。比如,一個(gè)最簡(jiǎn)單的操作用戶要點(diǎn)擊一個(gè)按鈕,而你的界面上到處都是按鈕圖片之類的,這就會(huì)讓用戶花上很長(zhǎng)的時(shí)間去尋找要點(diǎn)擊的按鈕,這樣一來,當(dāng)然就不能使用戶滿意了?;诖?本系統(tǒng)使用Qt來設(shè)計(jì)界面,并且共有2個(gè)界面窗口,分別是:播放器控制窗口、播放列表窗口、歌詞顯示窗口。為了更好地實(shí)現(xiàn)系統(tǒng)的各項(xiàng)功能與這些功能的完整性,現(xiàn)在把系統(tǒng)共分為以下2大模塊進(jìn)行設(shè)計(jì):<1>系統(tǒng)的播放控制窗口模塊<2>MP3文件的播放列表管理模塊<3>MP3歌詞的實(shí)時(shí)顯示模塊3.4.2界面窗口模塊詳細(xì)設(shè)計(jì)與實(shí)現(xiàn)一款軟件的界面設(shè)計(jì)的成敗直接關(guān)系到該產(chǎn)品的成敗。本MP3播放器系統(tǒng)的界面設(shè)計(jì),利用Qt提供的強(qiáng)大的控件設(shè)計(jì)而成。系統(tǒng)的界面窗口包括有2個(gè)主要的界面,分別是:播放器的控制界面窗口和媒體文件播放列表窗口,背景都為藍(lán)綠色調(diào),下面分別作出詳細(xì)介紹。控制界面窗口:播放器的控制界面是播放器系統(tǒng)與播放器的使用者直接交互的媒介。按照控制界面上的組件的功能來分,可以將這些組件分成兩部分:信息顯示和控制組件,如下圖3所示圖3控制界面窗口信息顯示組件信息顯示是系統(tǒng)與使用者進(jìn)行交流的通道,它可以與時(shí)地將各種有用的信息提供給用戶,以便用戶對(duì)系統(tǒng)進(jìn)行控制。本播放器系統(tǒng)的所有信息顯示在操作控件四周,很方便看到1.播放狀態(tài)顯示的作用,是與時(shí)準(zhǔn)確地顯示當(dāng)前播放器所處的狀態(tài)。其中,狀態(tài)有"播放"、"暫停"和"停止"三種,隨播放器狀態(tài)的改變而改變。2.音量顯示這部分與音量控制滑動(dòng)桿控件和菜單項(xiàng)中的"聲音"相關(guān)聯(lián),當(dāng)音量滑動(dòng)桿的滑塊位置改變以后,音量大小會(huì)隨著變化??刂平M件:信息顯示是播放器系統(tǒng)提供給使用者各種有用的信息,而控制組件則剛好相反,它可以看作是使用者提供給播放器系統(tǒng)的各種有用的信息,用來指示系統(tǒng)是否工作與如何工作。1>播放/暫停按鈕設(shè)計(jì)這個(gè)按鈕對(duì)一個(gè)播放器來說是最為重要的。如果一個(gè)播放器不能夠播放/暫停的話,就不能稱之為播放器了。對(duì)本播放器系統(tǒng)來說,這個(gè)按鈕集成了兩個(gè)重要的功能:"開始播放"和"暫停播放",這樣將兩個(gè)功能集成到一個(gè)位置上的好處就是減少了界面上的按鈕的個(gè)數(shù),這使得整個(gè)界面更加簡(jiǎn)潔。這個(gè)按鈕的作用是:如果當(dāng)前播放器的狀態(tài)為正在播放,點(diǎn)擊它之后就會(huì)暫停播放;如果當(dāng)前播放器的狀態(tài)為暫停播放,點(diǎn)擊它之后就會(huì)繼續(xù)播放。如果播放器的狀態(tài)沒有播放,也不是處于暫停狀態(tài),點(diǎn)擊之后,系統(tǒng)就會(huì)從媒體播放列表中加載一個(gè)媒體文件并開始播放。因此,基于上述功能,為實(shí)現(xiàn)播放和暫停功能,使之重疊放置,按照播放狀態(tài)的改變?cè)谕粫r(shí)間只顯示一個(gè)按鈕,這樣就模擬實(shí)現(xiàn)了播放/暫停功能按鈕,如果在播放狀態(tài)時(shí)想點(diǎn)擊播放按鈕播放其他MP3可以通過菜單中實(shí)現(xiàn)。表1播放器控件的組成部分組成控件功能播放/暫停按鈕播放當(dāng)前音樂文件或者暫停播放停止按鈕停止播放當(dāng)前音樂文件上一首按鈕播放列表中當(dāng)前MP3文件的上一首MP3文件下一首按紐播放列表中當(dāng)前MP3文件的下一首MP3文件打開按鈕選擇一首MP3文件列表按鈕顯示隱藏播放列表窗口歌詞按鈕顯示隱藏歌詞顯示窗口靜音按鈕打開/關(guān)閉播放器的輸出聲音音量控制條對(duì)播放器的音量大小進(jìn)行調(diào)節(jié)進(jìn)度控制條對(duì)當(dāng)前播放的MP3文件的播放進(jìn)度進(jìn)行調(diào)節(jié)2>停止按鈕的設(shè)計(jì)停止功能按鈕的設(shè)計(jì),是讓本播放器系統(tǒng)的使用者可以以手動(dòng)的方式來停止當(dāng)前媒體文件的播放。如果播放器當(dāng)前沒有文件正在進(jìn)行播放時(shí),該按鈕將置為無效狀態(tài),此時(shí)該按鈕不能點(diǎn)擊。3>上一首按鈕的設(shè)計(jì)如果沒有播放列表的話就不存在有多個(gè)媒體文件,也就不存在有上一首可以選擇了。所以,一個(gè)播放器的設(shè)計(jì)有這個(gè)功能按鈕的話,就表示它一定有一個(gè)用來保存媒體文件的播放列表。在本系統(tǒng)中,上一首按鈕設(shè)計(jì)在播放/暫停功能按鈕的前面。這樣設(shè)計(jì)的目的,是使得整個(gè)功能控制按鈕的順序與MP3文件在列表中的順序相似。4>下一首按鈕的設(shè)計(jì)同樣,它的設(shè)計(jì)也是與播放列表的存在有關(guān),如果沒有播放列表的話就不存在有多個(gè)媒體文件,也就不存在有下一首可以選擇了。在本系統(tǒng)中,下一首按鈕設(shè)計(jì)在播放/暫停功能按鈕的后面。這樣設(shè)計(jì)的目的,是使得整個(gè)功能控制按鈕的順序與文件在列表中的順序相似。5>打開按鈕的設(shè)計(jì)打開功能按鈕的設(shè)計(jì),是方便用戶選擇一個(gè)媒體文件,并立即進(jìn)行播放。6>列表按鈕的設(shè)計(jì)它主要是對(duì)播放列表窗口進(jìn)行顯示/隱藏控制,當(dāng)用戶點(diǎn)擊此按鈕后,如果當(dāng)前列表窗口的狀態(tài)為顯示狀態(tài)的話,用戶的操作將會(huì)隱藏列表窗口。相反,如果當(dāng)前列表窗口的狀態(tài)為隱藏狀態(tài),用戶的操作將會(huì)顯示列表窗口。7>歌詞按鈕的設(shè)計(jì)LRC是MP3歌詞文件的格式,此按鈕可以控制歌詞顯示窗口的顯示與隱藏。當(dāng)用戶點(diǎn)擊此按鈕時(shí),將檢查歌詞顯示窗口的狀態(tài)。如果當(dāng)前狀態(tài)為顯示,則將其隱藏;反之,如果當(dāng)前狀態(tài)為隱藏,則將其顯示。8〕靜音按鈕該按鈕可以控制播放器輸出聲音的開啟和關(guān)閉。當(dāng)用戶點(diǎn)擊此按鈕時(shí),系統(tǒng)將檢查播放器的聲音狀態(tài)。如果當(dāng)前聲音狀態(tài)為開啟,則將其管理,即靜音;如果當(dāng)前聲音狀態(tài)為關(guān)閉,則將其開啟。因?yàn)榕c音量控制有關(guān),所以在播放器中將其置于音量控制條的左方。9>音量控制條音量控制條的設(shè)計(jì)與音量大小和播放器的輸出音量關(guān)聯(lián),它的改變將直接影響播放器輸出音量的大小,其主要功能是用來控制系統(tǒng)播放媒體文件時(shí)發(fā)出的音量大小。10〕進(jìn)度控制條進(jìn)度控制條的設(shè)計(jì),是用來方便用戶進(jìn)行控制播放媒體文件進(jìn)度的,它的移動(dòng)將直接改變媒體文件的當(dāng)前播放進(jìn)度,同時(shí)歌詞顯示實(shí)時(shí)窗口的歌詞也將按照進(jìn)度進(jìn)行調(diào)整。當(dāng)控制條滑到最左邊時(shí)表示MP3文件的初始位置,當(dāng)控制條滑到最右邊時(shí)表示當(dāng)前位置為MP3文件的最后位置。播放列表界面:本播放器系統(tǒng)的播放列表窗口界面的設(shè)計(jì)主要是用來方便使用者配置管理播放器的播放列表,以提供給播放器更完整的功能。效果如圖4所示圖4播放列表界面MP3文件播放控制模塊詳細(xì)設(shè)計(jì)與實(shí)現(xiàn)MP3文件的播放控制模塊是本播放器系統(tǒng)的很重要的組成部分。在本播放器系統(tǒng)中,播放控制主要集中在對(duì)播放器的控制界面上的操作。首先說明的是,媒體播放器的播放控制的類型,如表2所示表2播放控制模塊組成控件功能播放按鈕從媒體文件打開播放或從暫停狀態(tài)繼續(xù)播放暫停暫停當(dāng)前MP3文件的播放停止停止播放當(dāng)前MP3音樂文件上一首播放列表中當(dāng)前MP3文件的上一首MP3文件下一首播放列表中當(dāng)前MP3文件的下一首MP3文件打開選擇一首MP3文件在本播放器中,總共有三種狀態(tài),即播放狀態(tài)、暫停狀態(tài)和停止?fàn)顟B(tài),通過表中所列的各種播放控制類型可以實(shí)現(xiàn)這三種狀態(tài)之間的轉(zhuǎn)換,其具體轉(zhuǎn)換如圖5〔見附錄1〕所示。下面將根據(jù)上圖的各種轉(zhuǎn)換關(guān)系,詳細(xì)介紹各種播放控制類型的設(shè)計(jì)與實(shí)現(xiàn)播放:播放功能是媒體播放器所有控制功能中最重要的一個(gè)功能,沒有了它,播放器不能播放,也就不能稱之為播放器了。在本播放器系統(tǒng)中,當(dāng)點(diǎn)擊播放會(huì)有三種狀態(tài)轉(zhuǎn)換:第一種是從播放狀態(tài)仍然轉(zhuǎn)換到播放狀態(tài);第二種是從停止?fàn)顟B(tài)轉(zhuǎn)換到播放狀態(tài);第三種是從暫停狀態(tài)轉(zhuǎn)換到播放狀態(tài)。下面具體介紹播放功能是怎樣設(shè)計(jì)的,其具體流程如圖6〔見附錄1〕所示。當(dāng)播放器接收到播放命令后,會(huì)依次執(zhí)行下面的過程:<1>檢查播放器的當(dāng)前狀態(tài)是否是暫停狀態(tài)。如果是暫停狀態(tài),那么繼續(xù)播放,如果不是暫停狀態(tài),則執(zhí)行第2步;<2>檢查播放列表中是否有媒體文件,如果沒有則調(diào)用添加歌曲過程進(jìn)行添加,然后再次執(zhí)行本過程進(jìn)行播放;如果播放列表中有文件則執(zhí)行第3步;<3>檢查播放列表索引,判斷是否選中了播放列表的一首MP3來進(jìn)行播放,如果沒有選擇,則選擇播放列表中的第一首后執(zhí)行第4步,如果已經(jīng)選擇了要播放的MP3則直接執(zhí)行第4步〔4>判斷要播放的MP3在播放列表中的位置,如果是第一首則將上一首按鈕置為無效,否則置為有效;如果是最后一首,則將下一首按鈕置為無效,否則置為有效。暫停:當(dāng)用戶播放一個(gè)媒體文件到某一個(gè)特定的點(diǎn)時(shí),由于某些原因需要暫停當(dāng)前媒體文件的播放,這就要求設(shè)計(jì)的媒體播放器具有暫停播放的功能。既然是暫停播放,那么它前面的狀態(tài)就必然是播放狀態(tài),即暫停狀態(tài)只能由播放狀態(tài)轉(zhuǎn)換而來。而這個(gè)狀態(tài)轉(zhuǎn)換的條件,就是在系統(tǒng)播放時(shí)用戶點(diǎn)擊暫停按鈕,暫停功能的流程如圖7〔見附錄1〕所示。停止播放:停止當(dāng)前MP3文件的播放有三種方式,第一種是當(dāng)播放器播放到當(dāng)前文件的最后,系統(tǒng)會(huì)自動(dòng)停止播放;第二種是用戶可以點(diǎn)擊停止播放按鈕來停止當(dāng)前媒體文件的播放。進(jìn)入停止?fàn)顟B(tài)的初始狀態(tài)也有兩種:第一種是播放狀態(tài);第二種是暫停狀態(tài),當(dāng)播放器轉(zhuǎn)換為停止?fàn)顟B(tài)后,暫停功能和停止功能都變?yōu)闊o效功能,不能使用,直到轉(zhuǎn)換到播放狀態(tài)。停止功能的設(shè)計(jì)流程如圖8〔見附錄1〕所示。當(dāng)播放器接收到停止命令后,會(huì)執(zhí)行以下過程:<1>設(shè)置各按鈕狀態(tài),播放為有效,暫停和停止置為無效;<2>檢查停止命令是用戶手動(dòng)停止,還是播放器播放完一首MP3后自動(dòng)轉(zhuǎn)換到停止?fàn)顟B(tài)。如果是手動(dòng)停止則使播放控件停止播放,計(jì)時(shí)器停止計(jì)時(shí),并將當(dāng)前播放進(jìn)度置0;如果是自然停止這執(zhí)行第3步;<3>檢查播放模式是否是單曲播放模式,如果是則結(jié)束停止過程,否則執(zhí)行第4步;<4>如果播放模式是循環(huán)播放且播放結(jié)束的是播放列表中的最后一首,這將播放列表的索引置0,否則直接播放下一首。上一首:上一首是針對(duì)播放列表所定義的操作。它是指用戶對(duì)播放器系統(tǒng)發(fā)送的命令〔播放上一首〕,然后由播放器系統(tǒng)做出播放上一首的反應(yīng)。因?yàn)樵诒静シ牌飨到y(tǒng)中,如果當(dāng)前播放的MP3文件是播放列表中的第一首時(shí),上一首功能設(shè)置為無效狀態(tài),所以在系統(tǒng)發(fā)送播放上一首命令時(shí),不需要檢查當(dāng)前播放的文件是否是播放列表中的第一文件,而可以執(zhí)行播放上一首的操作。上一首的具體流程如圖9〔見附錄1〕所示。下一首:同樣,播放下一首也是針對(duì)播放列表所定義的操作。它是指用戶對(duì)播放器系統(tǒng)發(fā)送播放下一首的命令,然后由播放器系統(tǒng)做出播放下一首的反應(yīng)。同樣,在本播放器系統(tǒng)中,如果當(dāng)前播放的文件是播放列表中最后一個(gè)文件,那么播放下一首功能會(huì)設(shè)置為無效狀態(tài),所以系統(tǒng)在響應(yīng)播放下一首命令時(shí),無需檢查當(dāng)前播放文件是否是播放列表的最后一個(gè)文件。它的具體操作過程是:當(dāng)用戶發(fā)送了播放下一首的命令后,系統(tǒng)就會(huì)停止當(dāng)前正在播放的文件,然后去播放當(dāng)前播放文件的后面一個(gè)文件。下一首功能的流程可參照?qǐng)D9。打開文件并播放:打開文件并播放是用戶通過點(diǎn)擊打開按鈕向系統(tǒng)發(fā)送的命令。當(dāng)系統(tǒng)接收到該命令時(shí),先會(huì)彈出一個(gè)打開文件對(duì)話框,然后由用戶選擇所要打開的MP3文件,把這個(gè)文件添加到播放列表,然后使用播放功能播放該文件。具體的操作流程如圖10〔見附錄1〕所示。向列表中添加單首MP3文件:向播放列表中添加媒體文件,都是在系統(tǒng)的播放列表窗口界面上進(jìn)行操作的,以添加單首MP3文件。具體的添加過程是:當(dāng)系統(tǒng)獲取了一個(gè)添加媒體文件的命令時(shí),會(huì)彈出一個(gè)文件對(duì)話框,等待用戶選擇媒體文件,這時(shí),用戶可以選擇一個(gè)MP3文件。當(dāng)用戶點(diǎn)擊文件對(duì)話框上的打開按鈕以后,用戶所選擇的MP3文件就會(huì)被添加到播放列表中供用戶查看和控制。刪除列表中的一首MP3文件:對(duì)播放列表有添加功能當(dāng)然也必然存在刪除操作。在對(duì)播放列表中的MP3文件進(jìn)行刪除操作時(shí),前提是播放列表中必須有一首MP3文件被選中,否則將不會(huì)有任何事件發(fā)生。其具體操作是:當(dāng)用戶想要?jiǎng)h除一個(gè)MP3文件時(shí),首先用鼠標(biāo)選擇該文件,然后右擊音樂曲目點(diǎn)擊刪除就可以了,剩下的工作由系統(tǒng)完成。其中,系統(tǒng)所做的工作是:記錄當(dāng)前用戶所刪除的文件在列表中的索引,然后根據(jù)這個(gè)索引值刪除掉播放列表中的該索引項(xiàng),然后系統(tǒng)會(huì)自動(dòng)將該項(xiàng)后面的項(xiàng)向前移動(dòng)一位。3.4.6主要程序文件〔代碼見附錄〕1〕頭文件<為類加入相應(yīng)的標(biāo)準(zhǔn)流,庫(kù)>lrcwindow.hmusiclist.hwidget.h2〕源文件〔完成各種類的定義與實(shí)現(xiàn)〕main.cpplrcwindows.cppmusiclist.cppwidget.cpp第四章調(diào)試分析QTcreator在使用的過程中也出現(xiàn)了很多問題,首先是版本的問題,一開始編寫調(diào)試程序的時(shí)候應(yīng)當(dāng)選擇在WINDOWS下能夠直接運(yùn)行的QTSDK,下一步就是在虛擬機(jī)下QTcreator的安裝這里要注意的問題就是QT編譯環(huán)境的建立。其次就是QTcreator的庫(kù)依賴問題,在創(chuàng)建工程的時(shí)候可以用GUI選擇你需要依賴的Qt模塊,這樣你可以僅僅通過包含頭文件名即可正確包含頭文件,但是沒有選擇的話,你需要包含相對(duì)目錄。我此次的任務(wù)是多媒體播放器的設(shè)計(jì),而播放器需要用到QTphonon。Qt從4.4版本開始提供的一套多媒體框架,提供多媒體回放的功能。目前在Qt4.6中實(shí)現(xiàn)多媒體播放圖形界面主要依賴于phonon框架,它能實(shí)現(xiàn)底層的多媒體播放功能,在一般情況下上層的接口phonon模塊更適合實(shí)現(xiàn)這些功能。phonon最初是一個(gè)源于KDE的項(xiàng)目為使用音頻和視頻的應(yīng)用程序開發(fā)提供的一個(gè)框架。應(yīng)用程序不用去管多媒體播放是通過什么實(shí)現(xiàn)的,如gstreamer、xine,只需調(diào)用相應(yīng)的接口就行,但這中間需要一個(gè)中轉(zhuǎn),被稱為backend。Qt也是通過phonon來實(shí)現(xiàn)夸平臺(tái)的多媒體播放。最終通過編譯后可看到如附錄2的界面,可以通過按鈕實(shí)現(xiàn)播放器的簡(jiǎn)單功能。第五章設(shè)計(jì)總結(jié)本次設(shè)計(jì)在Linux操作系統(tǒng)下,Qt作為嵌入式系統(tǒng)圖形用戶界面GUI,通過虛擬機(jī)的RedHatEnterpriseLinux5系統(tǒng)進(jìn)行模擬,基本完成了基于QT的多媒體播放器的實(shí)現(xiàn)。在嵌入式系統(tǒng)基礎(chǔ)上,主要分析了Linux操作系統(tǒng)的的特點(diǎn)和優(yōu)勢(shì),通過Linux系統(tǒng)下的QT編譯環(huán)境的學(xué)習(xí),了解了音頻解碼模塊,簡(jiǎn)單應(yīng)用的QTcreator下的phonon構(gòu)架設(shè)計(jì)了音樂播放器。不過本次設(shè)計(jì)過程中,由于時(shí)間因素的限制,對(duì)于QT庫(kù)的研究還不夠徹底,基于QT的播放器的設(shè)計(jì)與實(shí)現(xiàn)是需要依賴phonon框架的,我從網(wǎng)上下載的所有的版本都缺乏phonon庫(kù),使得在最終結(jié)果的實(shí)現(xiàn)有了很大的阻礙。此外,在虛擬機(jī)下運(yùn)行的QT也遇到了版本的問題,這些問題都將在以后的學(xué)習(xí)過程中加以解決。主要參考文獻(xiàn):1、邢吉生等.嵌入式系統(tǒng)設(shè)計(jì)與應(yīng)用,:大學(xué),20xx2、王勇編著.《嵌入式系統(tǒng)原理與設(shè)計(jì)》.XX:XX大學(xué),20xx3、<美>ChristopherHallinan著,華XX見嵌入式培訓(xùn)中心譯《嵌入式Linux基礎(chǔ)教程》,人民郵電,20xx4、俞輝主編,嵌入式Linux程序設(shè)計(jì)案例與實(shí)驗(yàn)教材,機(jī)械工業(yè),20xx5、韋東山主編,嵌入式Linux應(yīng)用開發(fā)完全手冊(cè),人民郵電,20xx版6、俞建新等編,嵌入式應(yīng)用程序開發(fā)綜合實(shí)驗(yàn)9例,清華大學(xué),20xx7、〔英〕薩默菲爾德著,白建平等譯,Qt高級(jí)編程,電子工業(yè)20xx8、X阿奇,《Qt4開發(fā)實(shí)踐》,電子工業(yè)。20xx附錄<流程圖、源代碼>:附錄1相關(guān)流程圖圖5播放的三種狀態(tài)圖6播放功能流程圖圖7暫停功能的流程圖8停止功能流程圖9上一首功能流程圖10打開功能操作流程附錄2系統(tǒng)運(yùn)行效果本播放器系統(tǒng)一共有3個(gè)界面窗口,分別是播放器的主控制窗口、播放列表窗口和歌詞顯示窗口。在此,將詳細(xì)介紹這些窗口在不同狀態(tài)下的圖示,尤其是播放器的主要播放控制窗口。播放器運(yùn)行時(shí)的整體效果如圖11所示:圖11播放器整體運(yùn)行時(shí)效果1.播放狀態(tài)時(shí)播放器主控制窗口界面此時(shí)播放器的主控制窗口界面如圖12所示。圖12播放狀態(tài)2.暫停狀態(tài)時(shí)播放器的主控制窗口界面此時(shí)播放器的主控制窗口界面如圖13所示圖13暫停狀態(tài)3.停止?fàn)顟B(tài)時(shí)播放的主控制窗口界面此時(shí)播放器的主控制窗口界面如圖14所示圖14停止?fàn)顟B(tài)播放器的列表窗口界面也是由兩部分組成的,第一部分是播放列表項(xiàng)目;第二部分是MP3媒體文件顯示列表。其界面窗口如圖15所示。圖15播放器的播放列表窗口界面效果附錄3程序源代碼lrcwindow.h:#ifndefLRCWINDOW_H#defineLRCWINDOW_H#include<QLabel>#include<QTimer>classlrcWindow:publicQLabel{Q_OBJECTpublic:lrcWindow<QWidget*parent>;QAction*exit;voidsetTime<intnum>{time=num;}voidsetLrcWidth<>;QTimer*timer;private:QPointdragPosition;inttime;qreallength;qreallrcWidth;protected:voidmousePressEvent<QMouseEvent*>;voidmouseMoveEvent<QMouseEvent*>;voidcontextMenuEvent<QContextMenuEvent*ev>;voidpaintEvent<QPaintEvent*>;privateslots:voidtimeout<>;};#endif//LRCWINDOW_Hmusiclist.h:#ifndefMUSICLIST_H#defineMUSICLIST_H#include<QWidget>namespaceUi{classmusicList;}classmusicList:publicQWidget{Q_OBJECTpublic:musicList<QWidget*parent=0>;~musicList<>;Ui::musicList*ui;voidlistReadSettings<>;voidlistWriteSettings<>;protected:voidchangeEvent<QEvent*e>;voidcloseEvent<QCloseEvent*>;voidmoveEvent<QMoveEvent*>;signals:voidlistClose<>;private:};#endif//MUSICLIST_Hwidget.h:#ifndefWIDGET_H#defineWIDGET_H#include<QWidget>#include<phonon>#include"lrcwindow.h"#include"musiclist.h"#include<QTimer>#include<QSystemTrayIcon>#include<QMenu>#include<QTextEdit>classQLabel;namespaceUi{classWidget;}classWidget:publicQWidget{Q_OBJECTpublic:Widget<QWidget*parent=0>;~Widget<>;voidcreatActions<>;voidsetCurrentLrc<>;protected:voidchangeEvent<QEvent*e>;voidwheelEvent<QWheelEvent*>;booleventFilter<QObject*,QEvent*>;voidcontextMenuEvent<QContextMenuEvent*>;voiddragEnterEvent<QDragEnterEvent*>;voiddropEvent<QDropEvent*>;voidcloseEvent<QCloseEvent*>;voidmoveEvent<QMoveEvent*>;voidmouseDoubleClickEvent<QMouseEvent*>;private:Ui::Widget*ui;musicList*mList;Phonon::MediaObject*audio;Phonon::MediaObject*musicInformationMediaObject;Phonon::VideoWidget*videoWidget;Phonon::AudioOutput*audioOutput;Phonon::SeekSlider*seekSlider;Phonon::VolumeSlider*volumeSlider;QList<Phonon::MediaSource>musicSourceList;QWidget*lrcWidget;QLabel*lrcLabel;lrcWindow*lrc;lrcWindow*lrc2;QTimer*timer;QIcon*iconplay;QIcon*iconpause;QAction*play;QAction*stop;QAction*open;QAction*sound;QAction*exit;QAction*remove;QSystemTrayIcon*trayicon;QMenu*trayiconMenu;voidreadSettings<>;voidwriteSettings<>;QTextEdit*text;boolisTouched;privateslots:voidon_toolButton_List_clicked<boolchecked>;voidtableWidget_cellDoubleClicked<introw,intcolumn>;voidon_toolButton_lrcD_clicked<boolchecked>;voidon_toolButton_next_clicked<>;voidon_toolButton_stop_clicked<>;voidon_toolButton_playpause_clicked<>;voidon_toolButton_previous_clicked<>;voidon_toolButton_open_clicked<>;voidshowTime<qint64>;voidTimeout<>;voidmusicInformationStateChanged<Phonon::State,Phonon::State>;voidmediaObjectStateChanged<Phonon::State,Phonon::State>;voidmusicAboutToFinish<>;voidcurrentMusicSourceChanged<Phonon::MediaSource>;voidremoveSlot<>;voidexitSlot<>;voidiconActivated<QSystemTrayIcon::ActivationReasonreason>;signals:voidmySignal<>;};#endif//WIDGET_Hmain.cpp:#include<QtGui/QApplication>#include"widget.h"#include<QTextCodec>intmain<intargc,char*argv[]>{QApplicationa<argc,argv>;QTextCodec::setCodecForTr<QTextCodec::codecForLocale<>>;Widgetw;w.show<>;returna.exec<>;}lrcwindow.cpp:#include"lrcwindow.h"#include<QMouseEvent>#include<QMenu>#include<QTimer>#include<QDebug>#include<QPainter>lrcWindow::lrcWindow<QWidget*parent>:QLabel<parent>{this->setWindowFlags<Qt::SubWindow|Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint>;this->resize<1024,60>;this->setText<tr<"Music...">>;this->setAttribute<Qt::WA_TranslucentBackground>;//背景透明this->setCursor<Qt::OpenHandCursor>;exit=newQAction<tr<"隱藏<&D>">,this>;connect<exit,SIGNAL<triggered<>>,this,SLOT<close<>>>;timer=newQTimer<this>;connect<timer,SIGNAL<timeout<>>,this,SLOT<timeout<>>>;this->move<400,700>;lrcWidth=0;}voidlrcWindow::mousePressEvent<QMouseEvent*event>{if<event->button<>==Qt::LeftButton>{dragPosition=event->globalPos<>-frameGeometry<>.topLeft<>;event->accept<>;}elseif<event->button<>==Qt::MidButton>//點(diǎn)擊鼠標(biāo)滾輪close<>;QLabel::mousePressEvent<event>;}voidlrcWindow::mouseMoveEvent<QMouseEvent*e>{if<e->buttons<>&Qt::LeftButton>{move<e->globalPos<>-dragPosition>;e->accept<>;}QLabel::mouseMoveEvent<e>;}voidlrcWindow::contextMenuEvent<QContextMenuEvent*ev>{QMenumenu;menu.addAction<exit>;menu.exec<ev->globalPos<>>;QLabel::contextMenuEvent<ev>;}voidlrcWindow::paintEvent<QPaintEvent*>{QPainterpainter<this>;//painter.setRenderHints<QPainter::Antialiasing|QPainter::TextAntialiasing>;//使用該行代碼可以實(shí)現(xiàn)反鋸齒,使歌詞顯示更漂亮,但是會(huì)明顯增加CPU占用率QFontfont<tr<"TimesNewRoman">,30,QFont::Bold>;painter.setFont<font>;QLinearGradientlg<0,20,0,50>;lg.setColorAt<0,QColor<0,170,255,255>>;lg.setColorAt<0.2,QColor<61,214,191,250>>;lg.setColorAt<0.5,QColor<85,255,255,255>>;lg.setColorAt<0.8,QColor<61,214,191,250>>;lg.setColorAt<1,QColor<0,170,255,255>>;painter.setBrush<lg>;painter.setPen<Qt::NoPen>;QPainterPathtextPath;textPath.addText<0,50,font,text<>>;painter.drawPath<textPath>;length=textPath.currentPosition<>.x<>;painter.setPen<Qt::yellow>;painter.drawText<0,14,lrcWidth,50,Qt::AlignLeft,text<>>;}voidlrcWindow::timeout<>{lrcWidth+=length/85;update<>;}voidlrcWindow::setLrcWidth<>{lrcWidth=0;}musiclist.cpp:#include"musiclist.h"#include"ui_musiclist.h"#include<QSettings>#include<QCloseEvent>musicList::musicList<QWidget*parent>:QWidget<parent>,ui<newUi::musicList>{ui->setupUi<this>;listReadSettings<>;ui->tableWidget->setAcceptDrops<true>;this->setWindowFlags<Qt::Tool>;}musicList::~musicList<>{deleteui;}voidmusicList::changeEvent<QEvent*e>{QWidget::changeEvent<e>;switch<e->type<>>{caseQEvent::LanguageChange:ui->retranslateUi<this>;break;default:break;}}voidmusicList::closeEvent<QCloseEvent*e>{emitlistClose<>;listWriteSettings<>;e->accept<>;}voidmusicList::listReadSettings<>//讀取播放列表的位置,大小信息{QSettingssettings<"yafeilinux","PhononLIST">;QPointpos=settings.value<"pos",QPoint<this->x<>,this->y<>+150>>.toPoint<>;QSizesize=settings.value<"size",QSize<300,320>>.toSize<>;move<pos>;resize<size>;}voidmusicList::listWriteSettings<>//記錄播放列表的位置,大小信息{QSettingssettings<"yafeilinux","PhononLIST">;settings.setValue<"pos",pos<>>;settings.setValue<"size",size<>>;}voidmusicList::moveEvent<QMoveEvent*e>{if<qAbs<<this->y<>-this->parentWidget<>->y<>-this->parentWidget<>->frameGeometry<>.height<>>><20>{this->move<this->x<>,this->parentWidget<>->y<>+this->parentWidget<>->frameGeometry<>.height<>>;}if<qAbs<this->x<>+this->frameGeometry<>.width<>-this->parentWidget<>->x<>><20>{this->move<this->parentWidget<>->x<>-this->frameGeometry<>.width<>,this->y<>>;}if<qAbs<this->x<>-this->parentWidget<>->frameGeometry<>.width<>-this->parentWidget<>->x<>><20>{this->move<this->parentWidget<>->x<>+this->parentWidget<>->frameGeometry<>.width<>,this->y<>>;}QWidget::moveEvent<e>;}widget.cpp:#include"widget.h"#include"ui_widget.h"#include"lrcwindow.h"#include"musiclist.h"#include"ui_musiclist.h"#include<QtGlobal>#include<QtGui>Widget::Widget<QWidget*parent>:QWidget<parent>,ui<newUi::Widget>{ui->setupUi<this>;mList=newmusicList<this>;mList->setFixedSize<300,320>;//固定播放列表的大小mList->ui->tableWidget->setColumnWidth<0,150>;mList->ui->tableWidget->setColumnWidth<1,150>;connect<mList->ui->tableWidget,SIGNAL<cellDoubleClicked<int,int>>,SLOT<tableWidget_cellDoubleClicked<int,int>>>;//mList->show<>;connect<mList,SIGNAL<listClose<>>,ui->toolButton_List,SLOT<toggle<>>>;text=newQTextEdit<this>;text->hide<>;//用于查找下句歌詞以計(jì)算時(shí)間間隔ui->textEdit->setVisible<false>;//文本編輯框不可見,〔解析歌詞〕this->setAcceptDrops<true>;this->setFixedSize<300,150>;this->setWindowTitle<tr<"音樂播放器">>;readSettings<>;//讀取上次關(guān)閉窗口時(shí)窗口的位置QPalettepalette=ui->label_lrc->palette<>;//設(shè)置窗體內(nèi)歌詞顏色palette.setColor<QPalette::WindowText,Qt::darkBlue>;ui->label_lrc->setPalette<palette>;lrc=newlrcWindow<0>;//桌面歌詞//lrc->show<>;/**初始化媒體**/audio=newPhonon::MediaObject<>;//媒體對(duì)象audio->setTickInterval<1>;audioOutput=newPhonon::AudioOutput<Phonon::VideoCategory>;//音頻輸出Phonon::createPath<audio,audioOutput>;//連接媒體對(duì)象與音頻輸出musicInformationMediaObject=newPhonon::MediaObject<this>;//音樂信息對(duì)象volumeSlider=newPhonon::VolumeSlider<audioOutput,this>;//音量滑動(dòng)條volumeSlider->move<190,80>;volumeSlider->resize<50,20>;volumeSlider->setStyleSheet<"background-color:rgb<255,255,255,100>">;volumeSlider->setFixedWidth<100>;//固定音量條大小seekSlider=newPhonon::SeekSlider<audio,this>;//進(jìn)度滑動(dòng)條seekSlider->move<10,35>;seekSlider->resize<170,20>;seekSlider->setStyleSheet<"background-color:rgb<255,255,255,100>">;connect<audio,SIGNAL<tick<qint64>>,this,SLOT<showTime<qint64>>>;//時(shí)間顯示與歌詞的更新connect<audio,SIGNAL<stateChanged<Phonon::State,Phonon::State>>,this,SLOT<mediaObjectStateChanged<Phonon::State,Phonon::State>>>;connect<musicInformationMediaObject,SIGNAL<stateChanged<Phonon::State,Phonon::State>>,this,SLOT<musicInformationStateChanged<Phonon::State,Phonon::State>>>;//當(dāng)加入新音樂時(shí)執(zhí)行connect<audio,SIGNAL<aboutToFinish<>>,this,SLOT<musicAboutToFinish<>>>;connect<audio,SIGNAL<currentSourceChanged<Phonon::MediaSource>>,this,SLOT<currentMusicSourceChanged<Phonon::MediaSource>>>;connect<lrc->exit,SIGNAL<triggered<bool>>,ui->toolButton_lrcD,SLOT<setChecked<bool>>>;timer=newQTimer<this>;//定時(shí)器,若0.1秒不顯示歌詞,則顯示"Music..."timer->start<100>;connect<timer,SIGNAL<timeout<>>,SLOT<Timeout<>>>;creatActions<>;mList->installEventFilter<this>;mList->ui->tableWidget->installEventFilter<this>;//事件過濾器connect<audioOutput,SIGNAL<mutedChanged<bool>>,sound,SLOT<setChecked<bool>>>;connect<this,SIGNAL<mySignal<>>,this,SLOT<close<>>,Qt::QueuedConnection>;}voidWidget::changeEvent<QEvent*e>{QWidget::changeEvent<e>;switch<e->type<>>{caseQEvent::LanguageChange:ui->retranslateUi<this>;break;caseQEvent::WindowStateChange:if<isMinimized<>>{emitmySignal<>;e->ignore<>;}default:break;}}voidWidget::mouseDoubleClickEvent<QMouseEvent*e>{QPointtemp=e->pos<>;constintpos_min_x=this->pos<>.x<>;constintpos_max_x=pos_min_x+this->width<>;constintpos_min_y=this->pos<>.y<>;constintpos_max_y=pos_min_y+this->height<>;if<temp.x<>>pos_min_x&&temp.x<><pos_max_x&&temp.y<>>pos_min_y&&temp.y<><pos_max_y>{//只對(duì)標(biāo)題欄X圍內(nèi)的鼠標(biāo)事件進(jìn)行處理this->close<>;}}voidWidget::moveEvent<QMoveEvent*e>{if<isTouched>{QPointp=e->pos<>-e->oldPos<>;mList->move<mList->pos<>+p>;}else{isTouched=false;if<qAbs<mList->y<>-this->y<>-this->frameGeometry<>.height<>><20>{isTouched=true;this->move<this->x<>,mList->y<>+this->frameGeometry<>.height<>>;}if<qAbs<this->x<>-mList->x<>-mList->frameGeometry<>.width<>><20>{isTouched=true;this->move<mList->x<>+mList->frameGeometry<>.width<>,this->y<>>;}if<qAbs<this->x<>+this->frameGeometry<>.width<>-mList->x<>><20>{isTouched=true;this->move<mList->x<>-this->frameGeometry<>.width<>,this->y<>>;}}QWidget::moveEvent<e>;}voidWidget::readSettings<>//讀取主窗口的位置信息{QSettingssettings<"yafeilinux","PhononExample">;QPointpos=settings.value<"pos",QPoint<400,200>>.toPoint<>;//QSizesize=settings.value<"size",QSize<298,412>>.toSize<>;move<pos>;//resize<size>;}voidWidget::writeSettings<>//記錄主窗口的位置信息{QSettingssettings<"yafeilinux","PhononExample">;settings.setValue<"pos",pos<>>;//settings.setValue<"size",size<>>;}voidWidget::closeEvent<QCloseEvent*e>//關(guān)閉事件{writeSettings<>;mList->listWriteSettings<>;if<this->isVisible<>>{this->hide<>;mList->hide<>;trayicon->showMessage<tr<"音樂播放器">,tr<"最小化到系統(tǒng)托盤,要關(guān)閉請(qǐng)右擊此圖標(biāo)選擇"退出"。">,QSystemTrayIcon::Information,15000>;e->ignore<>;}}boolWidget::eventFilter<QObject*object,QEvent*event>{qDebug<><<object;if<object==mList->ui->tableWidget>//過濾表格的事件{qDebug<><<"event"<<event;if<event->type<>==QEvent::ContextMenu>{QContextMenuEvent*contextevent=static_cast<QContextMenuEvent*><event>;QMenumenu<this>;menu.addAction<remove>;menu.exec<contextevent->globalPos<>>;returntrue;}elseif<event->type<>==QEvent::DragEnter>{QDragEnterEvent*dragEnterevent=static_cast<QDragEnterEvent*><event>;if<dragEnterevent->mimeData<>->hasFormat<"text/uri-list">>dragEnterevent->acceptProposedAction<>;returntrue;}elseif<event->type<>==QEvent::Drop>{QDropEvent*dropevent=static_cast<QDropEvent*><event>;dropEvent<dropevent>;returntrue;}elsereturnfalse;}returnQWidget::eventFilter<object,event>;}voidWidget::removeSlot<>//清空列表{audio->stop<>;intj=mList->ui->tableWidget->rowCount<>;for<inti=0;i<j;i++>{mList->ui->tableWidget->removeRow<0>;}mList->ui->tableWidget->close<>;mList->ui->tableWidget->show<>;audio->clear<>;musicSourceList.clear<>;}voidWidget::wheelEvent<QWheelEvent*wheelevent>//滾輪事件{if<wheelevent->delta<>>0>//上滾{qrealnewvolume=audioOutput->volume<>+<qreal>0.05;if<newvolume>=<qreal>1>newvolume=<qreal>1;audioOutput->setVolume<newvolume>;}else//下滾{qrealnewvolume=audioOutput->volume<>-<qreal>0.05;if<newvolume<=<qreal>0>newvolume=<qreal>0;audioOutput->setVolume<newvolume>;}}voidWidget::contextMenuEvent<QContextMenuEvent*e>{QMenumenu<this>;menu.addAction<play>;menu.addAction<stop>;menu.addAction<open>;menu.addSeparator<>;menu.addAction<sound>;menu.addSeparator<>;menu.addAction<exit>;menu.exec<e->globalPos<>>;}voidWidget::setCurrentLrc<>//設(shè)置當(dāng)前歌詞顯示{QStringfileName=audio->currentSource<>.fileName<>;QStringlrcName=fileName.remove<fileName.right<3>>+"lrc";QFilefile<lrcName>;if<!file.open<QFile::ReadOnly|QFile::Text>>{ui->label_lrc->setText<tr<"當(dāng)前目錄下未找到歌詞文件">>;lrc->setText<tr<"當(dāng)前目錄下未找到歌詞文件">>;}QTextStreamin<&file>;ui->textEdit->setText<in.readAll<>>;}voidWidget::Timeout<>//若0.1秒不顯示歌詞,則顯示"Music..."{if<lrc->text<>.isEmpty<>>{lrc->setText<tr<"yafeilinux">>;ui->label_lrc->setText<tr<"yafeilinux">>;}}voidWidget::showTime<qint64time>//時(shí)間與歌詞的更新顯示{qint64temp=audio->totalTime<>;QTimetotalTime<0,<temp/60000>%60,<temp/1000>%60,time%1000>;QTimecurTime<0,<time/60000>%60,<time/1000>%60,time%1000>;ui->label_time->setText<tr<"%1/%2">.arg<curTime.toString<"mm:ss">>.arg<totalTime.toString<"mm:ss">>>;ui->label_time->update<>;/**歌詞的更新顯示**/if<ui->textEdit->find<curTime.toString<"mm:ss.zzz">.left<7>>>//向后找{QStringstr=ui->textEdit->textCursor<>.block<>.text<>.replace<QRegExp<"\\[\\d{2}:\\d{2}\\.\\d{2}\\]">,"">;ui->label_lrc->setText<str>;lrc->setText<str>;lrc->setLrcWidth<>;//設(shè)置用于遮罩label的寬度為0//lrc->show<>;////////////////////////////////////////////////QTimett=curTime;intb=1;intc=0;text->setText<ui->textEdit->document<>->toPlainText<>>;boolover=ui->textEdit->textCursor<>.block<>.next<>.text<>.isEmpty<>;while<!over&&!text->find<tt.addMSecs<b*100>.toString<"mm:ss.zzz">.left<7>>>{b++;c++;}while<over&&!text->find<tt.addMSecs<b*100>.toString<"mm:ss.zzz">.left<7>,QTextDocument::FindBackward>>{b++;c++;break;}lrc->timer->start<c>;}//找不到后向前找elseif<ui->textEdit->find<curTime.toString<"mm:ss.zzz">.left<7>,QTextDocument::FindBackward>>{QStringstr=ui->textEdit->textCursor<>.block<>.text<>.replace<QRegExp<"\\[\\d{2}:\\d{2}\\.\\d{2}\\]">,"">;ui->label_lrc->setText<str>;lrc->setText<str>;lrc->setLrcWidth<>;//設(shè)置用于遮罩label的寬度為0//lrc->show<>;////////////////////////////////////////////////QTimett=curTime;intb=1;intc=0;text->setText<ui->textEdit->document<>->toPlainText<>>;boolover=ui->textEdit->textCursor<>.block<>.next<>.text<>.isEmpty<>;while<!over&&!text->find<tt.addMSecs<b*100>.toString<"mm:ss.zzz">.left<7>>>{b++;c++;}while<over&&!text->find<tt.addMSecs<b*100>.toString<"mm:ss.zzz">.left<7>,QTextDocument::FindBackward>>{b++;c++;break;}lrc->timer->start<c>;}}Widget::~Widget<>{deleteui;}voidWidget::creatActions<>{QIconiconremove<":/images/remove.png">;QIconiconstop<":/images/gtk-media-stop.png">;QIconiconopen<":/images/gtk-open.png">;QIconiconsound<":/images/sound.png">;QIconiconexit<":/images/exit.png">;iconpause=newQIcon<":/images/gtk-media-pause.png">;iconplay=newQIcon<":/images/gtk-media-play-ltr.png">;remove=newQAction<iconremove,tr<"清空播放列表">,this>;connect<remove,SIGNAL<triggered<>>,this,SLOT<removeSlot<>>>;play=newQAction<*iconplay,tr<"播放">,this>;connect<play,SIGNAL<triggered<>>,this,SLOT<on_toolButton_playpause_clicked<>>>;stop=newQAction<iconstop,tr<"停止">,this>;connect<stop,SIGNAL<triggered<>>,audio,SLOT<stop<>>>;open=newQAction<iconopen,tr<"打開文件">,this>;connect<open,SIGNAL<triggered<>>,this,SLOT<on_toolButton_open_clicked<>>>;sound=newQAction<iconsound,tr<"靜音">,this>;sound->setCheckable<true>;connect<sound,SIGNAL<triggered<bool>>,audioOutput,SLOT<setMuted<bool>>>;exit=newQAction<iconexit,tr<"退出">,this>;connect<exit,SIGNAL<triggered<>>,this,SLOT<exitSlot<>>>;/***系統(tǒng)托盤****/trayicon=newQSystemTrayIcon<this>;QIconico<":/images/VMP2.png">;trayiconMenu=newQMenu<this>;trayiconMenu->addAction<play>;trayiconMenu->addAction<stop>;trayiconMenu->addAction<open>;trayiconMenu->addSeparator<>;trayiconMenu->addAction<exit>

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論