图形界面开发报告模板 - 副本.doc_第1页
图形界面开发报告模板 - 副本.doc_第2页
图形界面开发报告模板 - 副本.doc_第3页
图形界面开发报告模板 - 副本.doc_第4页
图形界面开发报告模板 - 副本.doc_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

北京理工大学珠海学院图形界面开发课程报告20132014学年第1 学期题目: 基于QT的音乐播放器 学 院: 计算机科学技术学院 专业班级: 11级计算机五班 学 号:110201051008 110201051019 学生姓名: 黄志成 陈嘉辉 谭杰飞 指导教师: 翁省辉 成 绩: 时 间: 2013年11月30日北京理工大学珠海学院课程报告课程报告成绩评定表姓 名项目分工分数陈嘉辉黄志成谭杰飞26北京理工大学珠海学院课程报告基于QT的音乐播放器摘 要本次设计主要是解析如果用QT技术实现一个单机版的音乐播放器,本设计主要是使用phonon多媒体框架实现硬盘的播放。本软件可以播放常见的音频格式,如:mp3、wma等。软件的界面主要分为主界面、播放列表界面和桌面歌词界面。主界面有播放音乐主要的按键如播放/暂停按键、还有显示音乐的进度条等,播放列表界面有显示列表中的音乐、添加、删除按钮等。桌面歌词界面主要是显示歌词,如果有歌词则显示,否则显示播放器信息。关键词: 音乐播放器;QT目录课程报告成绩评定表11. 绪论31.1课题背景31.2课题意义32.关键技术分析42.1 QT42.1.1 QT简介42.1.2 QT的优点和特性42.2 phonon简介43.环境配置53.1安装Qt53.2配置Qt74. 系统设计75. 播放器具体实现75.1播放器主界面的实现85.1.1播放器主界面的初始化模块85.1.2更新标签显示的播放时间和歌词模块105.1.3播放或暂停模块115.1.4打开文件模块125.1.5媒体对象状态模块125.2播放列表实现145.2.1设计MyPlaylist类145.2.2解析媒体文件的元信息模块165.2.3改变主界面图标的状态186.结论23参考文献23心得体会251. 绪论1.1课题背景音乐播放器就是音频解码器的可视化操作界面,其实质是针对各种音频编码格式的解码器。例如ape格式调用的是Monkeys Audio解码器,flac格式调用的是flac解码器,mp3调用的是lame解码器。大部分音乐播放器都支持多种音乐格式的文件,这是因为这些播放器将不同的音频解码器打包起来,并制作统一的播放界面,从而让使用者能够方便地播放和聆听各种音乐。正因为音乐播放器仅仅是将音频解码器打包,而同一种音频的解码方式又是固定的,因此理论上所有播放器的音质应当是完全相同的,并不存在音质最好的音乐播放器。有些音乐播放器会在解码器的基础上添加DSP插件,对原始的音乐进行转换和扭曲,以迎合人们的喜好(如加强低音或过滤细节),美其名曰优化音质以获得天籁之音,实质却是破坏原本音乐,虽然能够使部分音乐更好听,却也导致另一些音乐音质大打折扣。音乐播放器的人性化界面和扩展性才是各种音乐播放器的特色所在。大部分商业版播放软件往往将界面打造得非常华丽,操作也十分简便,但却缺乏扩展性,支持格式较少。开源播放软件一般能够较好地进行扩展,支持较多的音乐格式,但往往界面朴素,难以吸引用户。1.2课题意义音乐播放器是一种用于播放各种音乐文件的多媒体播放软件。它涵盖了各种音乐格式的播放工具,比如:MP3播放器,WMA播放器,MP4播放器等。它们不仅界面美观,而且操作简单,带我们进入一个完美的音乐空间。而现今市场上大部分流行的音乐播放器虽然功能强大、界面漂亮,但操作起来确是非常复杂。对于初学电脑的人来说无疑操作难度较大,不知如何使用。本文设计的是一款基于QT的本地音乐播放器,本播放器功能完善、界面美观,具备了一般音乐播放器最重要和最核心的功能。而且操作难度低、界面简洁。2.关键技术分析2.1 QT2.1.1 QT简介Qt是一个1991年由奇趣科技开发的跨平台C+图形用户界面应用程序开发框架。它既可以开发GUI程式,也可用于开发非GUI程式,比如控制台工具和服务器。Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器(Meta Object Compiler, moc))以及一些宏,易于扩展,允许组件编程。2.1.2 QT的优点和特性优良的跨平台特性:Qt支持下列操作系统: Microsoft Windows 95/98, Microsoft Windows NT, Linux, Solaris, SunOS, HP-UX, Digital UNIX (OSF/1, Tru64), Irix, FreeBSD, BSD/OS, SCO, AIX, OS390,QNX 等等。面向对象:Qt 的良好封装机制使得 Qt 的模块化程度非常高,可重用性较好,对于用户开发来说是非常 方便的。 Qt 提供了一种称为 signals/slots 的安全类型来替代 callback,这使得各个元件 之间的协同工作变得十分简单。丰富的 API:Qt 包括多达 250 个以上的 C+ 类,还提供基于模板的 collections, serialization, file, I/O device, directory management, date/time 类。甚至还包括正则表达式的处理 功能。支持 2D/3D 图形渲染,支持 OpenGL大量的开发文档XML 支持。2.2 phonon简介Phonon是KDE 4的多媒体API 。Phonon提供一个稳定的API允许KDE 4独立于任何一个声音系统服务器如xine。Phonon让各种后端提供界面给开发者所谓的引擎;每个引擎运作在一个具体的后端。每个后端都可让Phonon控制基本功能,如播放、暂停和搜寻。Phonon也支持更高层次的功能,如让音轨转化之间变微弱。 使用Solid,Phonon将给予用户更多配件的控制能力如耳机、扬声器、麦克风。一个例子是,因为你可能只有一个VoIP会话使用您的耳机,但所有其他的声音通过扬声器出来。支援 Unix-like 系统下的后端xine、VLC、MPlayer。支援 Windows 下的后端 DirectShow、VLC和MPlayer.支援 Mac OS X下的后端QuickTime。QT4.4和之后版本使用了Phonon,作为跨平台的音频/视频播放。3.环境配置3.1安装Qt 由于QT5.0以上版本不包含phonon库,所以选择安装qt.4.7。可以在其官网上免费获取()安装QT4.7步骤如下:图1 开始QT安装图2 QT安装选项图3 QT安装路径图4 正在安装图5安装完成3.2配置Qt打开Qt,选择file,选择new file or project新建工程,按choose,输入工程名和路径后按next,选择QWidget按next-finish-finish。建立工程后在pro文件上加上“QT += phonon”添加phonon控件。4. 系统设计播放器的实现主要分为三大模块:播放器主界面,播放列表窗口和桌面歌词部件。播放器的设计流程如下图所示:媒体源 *mp3解析歌曲文件,获取歌曲信息媒体对象MediaObject播放解析歌词文件播放列表MyPlaylist类终止暂停显示桌面歌词 MyLrc类增添、删除、清空 图6 播放器设计流程图流程图的描述如下:在播放器中打开MP3等音乐文件后,会对这些文件进行解析,获得歌曲的标题,艺术家和长度等信息,然后在播放列表中显示出来。可以单击把播放列表中的一个歌曲来进行播放,并使用Phonon:MediaObject对象来进行音乐播放器的控制。当要播放一个歌曲时,就解析该歌曲。5. 播放器具体实现5.1播放器主界面的实现播放器的主界面有MyWidget类来实现,继承自QWidget类,主要用来实现音乐的播放控制,获取歌曲文件信息并构建播放列表窗口,解析歌词文件并构建桌面歌词部件。5.1.1播放器主界面的初始化模块该函数用于初始化播放器,包括设置主界面外观、初始化所有变量、创建媒体图等。主界面初始化的主要代码如下:void MyWidget:initPlayer() /* 设置主界面标题、图标和大小*/ setWindowTitle(tr(千千静听); setWindowIcon(QIcon(:/image/music.png); setMinimumSize(400, 160); setMaximumSize(400, 160); /* 创建媒体图*/ mediaObject = new Phonon:MediaObject(this); Phonon:AudioOutput *audioOutput = new Phonon:AudioOutput(Phonon:MusicCategory, this); Phonon:createPath(mediaObject, audioOutput); /*关联媒体对象的tick()信号来更新播放时间的显示*/ connect(mediaObject, SIGNAL(tick(qint64), this, SLOT(updateTime(qint64); ./这里省略的代码为创建界面的代码 / 创建用来解析媒体的信息的元信息解析器 metaInformationResolver = new Phonon:MediaObject(this); / 需要与AudioOutput连接后才能使用metaInformationResolver来获取歌曲的总时间 Phonon:AudioOutput *metaInformationAudioOutput =new Phonon:AudioOutput(Phonon:MusicCategory, this); Phonon:createPath(metaInformationResolver, metaInformationAudioOutput); connect(metaInformationResolver, SIGNAL(stateChanged(Phonon:State, Phonon:State),this, SLOT(metaStateChanged(Phonon:State, Phonon:State); connect(mediaObject, SIGNAL(currentSourceChanged(Phonon:MediaSource),this, SLOT(sourceChanged(Phonon:MediaSource); connect(mediaObject, SIGNAL(aboutToFinish(), this, SLOT(aboutToFinish(); / 初始化动作图标的状态 playAction-setEnabled(false); stopAction-setEnabled(false); skipBackwardAction-setEnabled(false); skipForwardAction-setEnabled(false); topLabel-setFocus(); / 创建歌词部件 lrc = new MyLrc(this); / 创建系统托盘图标 trayIcon = new QSystemTrayIcon(QIcon(:/image/music.png), this); trayIcon-setToolTip(tr(MyPlayer音乐播放器 - 陈嘉辉、黄志成、谭杰飞作品); /* 创建菜单*/ QMenu *menu = new QMenu; QList actions; actions playAction stopAction skipBackwardAction addActions(actions); menu-addSeparator(); menu-addAction(playListAction); menu-addAction(LRCAction); menu-addSeparator(); menu-addAction(tr(退出), qApp, SLOT(quit(); trayIcon-setContextMenu(menu); / 托盘图标被激活后进行处理 connect(trayIcon,SIGNAL(activated(QSystemTrayIcon:ActivationReason),this, SLOT(trayIconActivated(QSystemTrayIcon:ActivationReason); / 显示托盘图标 trayIcon-show();播放器主界面如图10图7 播放器主界面5.1.2更新标签显示的播放时间和歌词模块这里使用MediaObject类中的totalTime()函数获取了当前播放歌曲的总时间,单位也是毫秒。然后通过转换当前时间和总时间显示在timeLabel标签中,而且还可以在播放时更新歌词的显示。主要的代码如下:void MyWidget:updateTime(qint64 time) qint64 totalTimeValue = mediaObject-totalTime(); QTime totalTime(0, (totalTimeValue / 60000) % 60, (totalTimeValue / 1000) % 60); QTime currentTime(0, (time / 60000) % 60, (time / 1000) % 60); QString str = currentTime.toString(mm:ss) + / + totalTime.toString(mm:ss); timeLabel-setText(str); / 获取当期时间对应的歌词 if(!lrcMap.isEmpty() / 获取当前时间在歌词中的前后两个时间点 qint64 previous = 0; qint64 later = 0; foreach (qint64 value, lrcMap.keys() if (time = value) previous = value; else later = value; break; / 达到最后一行,将later设置为歌曲总时间的值 if (later = 0) later = totalTimeValue; / 获取当前时间所对应的歌词内容 QString currentLrc = lrcMap.value(previous); / 如果是新的一行歌词,那么重新开始显示歌词遮罩 if(currentLrc != lrc-text() lrc-setText(currentLrc); / topLabel-setText(currentLrc); qint64 intervalTime = later - previous; lrc-startLrcMask(intervalTime); / 如果没有歌词文件,则在顶部标签中显示歌曲标题 topLabel-setText(QFileInfo(mediaObject- currentSource().fileName().baseName();5.1.3播放或暂停模块这是播放动作playAction的触发信号对应的槽的定义,用来实现歌曲的播放和暂停的控制。主要代码如下:void MyWidget:setPaused() / 如果先前处于播放状态,那么暂停播放;否则,开始播放 if (mediaObject-state() = Phonon:PlayingState) mediaObject-pause(); else mediaObject-play();播放状态下如下图:图8 播放状态暂停状态下如下图:图9 暂停状态5.1.4打开文件模块这里用文件对话框QFileDialog,用户可以选择一个或多个文件或目录,将歌曲文件添加到播放列表中。主要代码如下:void MyWidget:openFile() / 从系统音乐目录打开多个音乐文件 QStringList list = QFileDialog:getOpenFileNames(this, tr(打开音乐文件),QDesktopServices:storageLocation(QDesktopServices:MusicLocation); if (list.isEmpty() return; / 获取当前媒体源列表的大小 int index = sources.size(); / 将打开的音乐文件添加到媒体源列表后 foreach (QString string, list) Phonon:MediaSource source(string); sources.append(source); / 如果媒体源列表不为空,则将新加入的第一个媒体源作为当前媒体源, / 这时会发射stateChanged()信号,从而调用metaStateChanged()函数进行媒体源的解析 if (!sources.isEmpty() metaInformationResolver-setCurrentSource(sources.at(index);5.1.5媒体对象状态模块这里根据媒体对象的不同状态进行了不同的处理。currentSource().fileName()可以获取当前播放的媒体源的路径,然后使用QFileInfo类的baseName()函数可以获取其中的文件名。主要代码如下:void MyWidget:stateChanged(Phonon:State newState, Phonon:State oldState) switch (newState) case Phonon:ErrorState : if(mediaObject-errorType() = Phonon:FatalError) QMessageBox:warning(this, tr(致命错误),mediaObject-errorString(); else QMessageBox:warning(this, tr(错误), mediaObject-errorString(); break; case Phonon:PlayingState : stopAction-setEnabled(true); playAction-setIcon(QIcon(:/image/pause.ico); playAction-setText(tr(暂停(F5); topLabel-setText(QFileInfo(mediaObject-currentSource().fileName().baseName(); /解析当前媒体源对应的歌词文件 resolveLrc(mediaObject-currentSource().fileName(); break; case Phonon:StoppedState : stopAction-setEnabled(false); playAction-setIcon(QIcon(:/image/start.ico); playAction-setText(tr(播放(F5); timeLabel-setText(tr(00:00 / 00:00); / 停止歌词遮罩 lrc-stopLrcMask(); lrc-setText(tr(MyPlayer音乐播放器 - 陈嘉辉、黄志成、谭杰飞作品); break; case Phonon:PausedState : stopAction-setEnabled(true); playAction-setIcon(QIcon(:/image/start.ico); playAction-setText(tr(播放(F5); topLabel-setText(QFileInfo(mediaObject-currentSource().fileName().baseName() + tr( 已暂停!); / 如果该歌曲有歌词文件 if (!lrcMap.isEmpty() lrc-stopLrcMask(); / lrc-setText(topLabel-text(); break; case Phonon:BufferingState : break; default : ; 5.2播放列表实现播放列表窗口由MyPlaylist类来实现,继承QTabelWidget类,主要用来显示播放列表。然后进行歌曲解析,使用歌曲标题、艺术家和长度等信息来创建播放列表。5.2.1设计MyPlaylist类设计播放列表主要是设计MyPlaylist类,继承自QTabelWidget类,这里需要实现两个功能:能在播放列表上进行添加、删除、清空歌曲功能;关闭播放列表时只是隐藏它而不让它退出。主要代码如下:MyPlaylist:MyPlaylist(QWidget *parent) : QWidget(parent) setWindowTitle(tr(播放列表); / 设置窗口标志,表明它是一个独立窗口且有一个只带有关闭按钮的标题栏 setWindowFlags(Qt:Window | Qt:WindowTitleHint); / 设置初始大小,并且锁定部件宽度 resize(400, 400); setMaximumWidth(400); setMinimumWidth(400); List1=new QTableWidget; List1-setSelectionMode(QAbstractItemView:ExtendedSelection); / 设置行列数目 List1-setRowCount(0); List1-setColumnCount(3); / 设置表头标签 QStringList Mylist; Mylist tr(标题) tr(艺术家) setHorizontalHeaderLabels(Mylist); / 设置只能选择单行 List1-setSelectionMode(QAbstractItemView:SingleSelection); List1-setSelectionBehavior(QAbstractItemView:SelectRows); append=new QPushButton(tr(添加); Delete=new QPushButton(tr(删除); clear=new QPushButton(tr(清空); connect(append, SIGNAL(clicked(), this, SLOT(appendPlaylist(); connect(Delete, SIGNAL(clicked(), this, SLOT(DeletePlaylist(); connect(clear, SIGNAL(clicked(), this, SLOT(clearPlaylist(); btnLayout=new QGridLayout(this); btnLayout-addWidget(List1,0,0,5,7); btnLayout-addWidget(append,5,1,1,1); btnLayout-addWidget(Delete,5,3,1,1); / btnLayout-addWidget(DeleteChoose,5,4,1,1); btnLayout-addWidget(clear,5,5,1,1); / 设置不显示网格 List1-setShowGrid(false);/ 关闭事件处理函数,如果部件处于显示状态,则使其隐藏void MyPlaylist:closeEvent(QCloseEvent *event) if (isVisible() hide(); event-ignore(); 播放列表界面如下图:图10 播放列表1添加上歌曲后:图11 播放列表25.2.2解析媒体文件的元信息模块打开歌曲文件后,将它们设置为媒体源添加到媒体源列表的后面,然后调用函数setCurrentSource()设置新添加的第一个媒体源为解析器的当前媒体源,这时解析器就会改变状态而进入加载状态,等加载完成后,又会进入停止状态。因为在initPlayer()函数中关联了解析器状态改变时发射的stateChanged()信号到metaStateChange()槽上,所以这时就会执行该槽来进行媒体源的解析。主要代码如下:void MyWidget:metaStateChanged(Phonon:State newState, Phonon:State oldState) / 错误状态,则从媒体源列表中除去新添加的媒体源 if(newState = Phonon:ErrorState) QMessageBox:warning(this, tr(打开文件时出错), metaInformationResolver-errorString(); while (!sources.isEmpty() & !(sources.takeLast() = metaInformationResolver-currentSource() ; return; / 如果既不处于停止状态也不处于暂停状态,则直接返回 if(newState != Phonon:StoppedState & newState != Phonon:PausedState) return; / 如果媒体源类型错误,则直接返回 if(metaInformationResolver-currentSource().type() = Phonon:MediaSource:Invalid) return; / 获取媒体信息 QMap metaData = metaInformationResolver-metaData(); / 获取标题,如果为空,则使用文件名 QString title = metaData.value(TITLE); if (title = ) QString str = metaInformationResolver-currentSource().fileName(); title = QFileInfo(str).baseName(); QTableWidgetItem *titleItem = new QTableWidgetItem(title); / 设置数据项不可编辑 titleItem-setFlags(titleItem-flags() Qt:ItemIsEditable); / 获取艺术家信息 QTableWidgetItem *artistItem = new QTableWidgetItem(metaData.value(ARTIST); artistItem-setFlags(artistItem-flags() Qt:ItemIsEditable); / 获取总时间信息 qint64 totalTime = metaInformationResolver-totalTime(); QTime time(0, (totalTime / 60000) % 60, (totalTime / 1000) % 60); QTableWidgetItem *timeItem = new QTableWidgetItem(time.toString(mm:ss); / 插入到播放列表 int currentRow = playlist-List1-rowCount(); playlist-List1-insertRow(currentRow); playlist-List1-setItem(currentRow, 0, titleItem); playlist-List1-setItem(currentRow, 1, artistItem); playlist-List1-setItem(currentRow, 2, timeItem); / 如果添加的媒体源还没有解析完,那么继续解析下一个媒体源 int index = sources.indexOf(metaInformationResolver-currentSource() + 1; if (sources.size() index) metaInformationResolver-setCurrentSource(sources.at(index); else / 如果所有媒体源都已经解析完成 / 如果播放列表中没有选中的行 if (playlist-List1-selectedItems().isEmpty() / 如果现在没有播放歌曲则设置第一个媒体源为媒体对象的当前媒体源 /(因为可能正在播放歌曲时清空了播放列表,然后又添加了新的列表) if (mediaObject-state() != Phonon:PlayingState & mediaObject-state() != Phonon:PausedState) mediaObject-setCurrentSource(sources.at(0); else /如果正在播放歌曲,则选中播放列表的第一个曲目,并更改图标状态 playlist-List1-selectRow(0); changeActionState(); else / 如果播放列表中有选中的行,那么直接更新图标状态 changeActionState(); 这部分主要完成了媒体源的元数据的解析功能,并将解析出来的信息添加到了播放列表中。 5.2.3改变主界面图标的状态当播放列表的内容改变时,还要更改主界面上的图标的状态,这个功能由changeActionState()函数来完成。主要代码如下:void MyWidget:changeActionState() / 如果媒体源列表为空 if (sources.count() = 0) / 如果没有在播放歌曲,则播放和停止按钮都不可用 /(因为可能歌曲正在播放时清除了播放列表) if (mediaObject-state() != Phonon:PlayingState & mediaObject-state() != Phonon:PausedState) playAction-setEnabled(false); stopAction-setEnabled(false); skipBackwardAction-setEnabled(false); skipForwardAction-setEnabled(false); else / 如果媒体源列表不为空 playAction-setEnabled(true); stopAction-setEnabled(true); / 如果媒体源列表只有一行 if (sources.count() = 1) skipBackwardAction-setEnabled(false); skipForwardAction-setEnabled(false); else / 如果媒体源列表有多行 skipBackwardAction-setEnabled(true); skipForwardAction-setEnabled(true); int index = playlist-List1-currentRow(); / 如果播放列表当前选中的行为第一行 if (index = 0) skipBackwardAction-setEnabled(false); / 如果播放列表当前选中的行为最后一行 if (index + 1 = sources.count() skipForwardAction-setEnabled(false); 当播放的媒体源改变时,媒体对象会发射currentSourceChange()信号,这时要在播放列表中选中对应的曲目,然后更新图标的状态。主要代码如下:void MyWidget:sourceChanged(const Phonon:MediaSource &source) int index = sources.indexOf(source); playlist-List1-selectRow(index); changeActionState();当前媒体源播放将要结束时,如果在列表中当前媒体源的后面还有媒体源,那么将它添加到播放队列中,否则停止播放。主要代码如下:void MyWidget:aboutToFinish() int index = sources.indexOf(mediaObject-currentSource() + 1; if (sources.size() index) mediaObject-enqueue(sources.at(index); / 跳转到歌曲最后 mediaObject-seek(mediaObject-totalTime(); / 停止歌词遮罩并重新解析歌词 lrc-stopLrcMask(); resolveLrc(sources.at(index).fileName(); else mediaObject-stop(); 当在播放列表中单击了一首歌曲时,要将其设置为当前的媒体源,并根据媒体对象的状态来判断是否进行播放。主要代码如下:void MyWidget:tableClicked(int row) / 首先获取媒体对象当前的状态,然后停止播放并清空播放队列 bool wasPlaying = mediaObject-state() = Phonon:PlayingState; mediaObject-stop(); mediaObject-clearQueue(); / 如果单击的播放列表中的行号大于媒体源列表的大小,则直接返回 if(row = sources.size() return; / 设置单击的行对应的媒体源为媒体对象的当前媒体源 mediaObject-setCurrentSource(sources.at(row); /*开始播放选中的曲目*/ mediaObject-play();当清空了播放列表时也要清空媒体源列表。主要代码如下:void MyWidget:clearSources() sources.clear(); / 更改动作图标状态 changeActionState();5.3桌面歌词的实现5.3.1桌面歌词类MyLrc的设计桌面歌词模块如图:图12 桌面歌词主要代码如下:setWindowFlags(Qt:Window | Qt:FramelessWindowHint); / 设置背景透明 setAttribute(Qt:WA_TranslucentBackground); setText(tr(MyPlayer音乐播放器 - 陈嘉辉、黄志成、谭杰飞作品); / 固定部件大小 setMaximumSize(1000, 60); s

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论