

已阅读5页,还剩27页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
摘 要本课程设计以当前对嵌入式多媒体设备需求量大为背景,提出了一个基于qt的适用于嵌入式设备的多媒体播放系统的架构设计方案。论文给出了一种嵌入式系统中音频视频同步的解决方案,有效的提高了嵌入式多媒体播放系统的音频视频同步性能,在此基础上设计并实现了基于linux/qt的嵌入式多媒体播放器,实现了基于qt的嵌入式多媒体播放器系统。关键词:qt;多媒体播放器;嵌入式abstractbased on the demand for wireless multimedia terminal project background, the media player architecture for embedded systems design.the paper gives thetenor of an embedded system video synchronization solutions,and effec- tively improve the synchronization performance of the embedded media player software,audio and video, designed and implemented based on the linux /qt embeddedmedia player on this basis , qt-based embedded media player system.keywords: the qt;embedded linux;media player目 录摘 要1abstract21引言52嵌入式多媒体播放器系统的设计63插件接口模块和解码库模块83.1插件接口模块设计83.1.1文件特性函数83.1.2获取文件信息函数83.1.3读取音频采样函数83.1.4视频帧函数83.1.5音视频同步函数83.2解码库模块94嵌入式多媒体播放器系统的实现104.1数据流程的总体设计104.2嵌入式音频视频同步设计115多媒体播放系统在pc端的实现135.1pc端环境的搭建135.2mplayer项目工程的建立与开发135.2.1mplayer工程的建立135.2.2mplayer实现原理145.2.3mplayer 界面ui搭建175.2.4mplayer 代码编写175.2.5mplayer 工程编译与运行结果186总结20参考文献21致 谢22附 录231引言随着用户要求的不断提高,越来越多的嵌入式设备使用的功能强大、价格低廉的嵌入式linux作为操作系统并开始采用较为复杂的图形界面。qt以其强大地功能、良好地可移植性逐渐成为一种被广泛使用的gui系统。正是由于嵌入式操作系统及其相应图形界面的不断发展,嵌入式软件的开发显得越来越重要。其中嵌入式多媒体播放器由于能满足人们的视听享受已经逐渐成为了系统中不可或缺的重要组成部分,在嵌入式系统开发多媒体播放器已经成为一个技术热点,当前许多嵌入式产品中都包含多媒体播放器。因此基于qt的嵌入式系统中实现多媒体播放器具有深刻的意义和价值。2嵌入式多媒体播放器系统的设计2.1架构设计嵌入式多媒体播放器架构设计方案如图1所示。通过使用纯c+语言来支持嵌入式linux系统,采用qt/embedded作为gui来提供强大的用户界面,实现一个开放式的插件接口来增强扩展性,利用内核帧缓冲来输出,消除对特定架构的依赖,从而保证可移植性。多媒体播放器属于上层应用程序,位于linux用户空间。这样设计的目的是为了系统的移植性。图形用户界面窗口已qt/embedded为基础开发,通过调用qt/embedded提供的类库根据需要设计可以管理多媒体文件的基本窗口,包括打开、删除、显示文件长度、显示播放时间等窗口,以及为方便用户设定的管理播放列表、进行播放控制的窗口,这些都是直接和用户打交道的。由于采用了qt/embedded最为gui,可移植性得到了保证。文件输入主要是对用户指定的文件进行读取和解析,将获得文件的长度、播放时间、编码格式、音视频帧率、文件标题等内容,结合mime的处理,显示预先设计的窗口中。插件接口调用主要是把所有对解码器的操作整合到一个统一的开放式接口当中,根据上一部分解析出的文件信息区查找相应的解码器插件并调用,如果没有找到可用的解码器可以返回信息提醒用户添加相应的插件。通过实现这样一个接口可以使播放器的扩展性大大提高,因此本部分使多媒体播放器的核心。文件解码和输出主要负责通过调用解码器对音视频数据流进行解码,然后利用qt/embedded可以直接操纵内核帧缓冲framebuffer的特性,将解码之后的数据通过framebuffer直接送到输出设备输出,避免对directshow、opengl等特定架构的依赖,进一步增强可移植性。图1 嵌入式多媒体播放器架构图3插件接口模块和解码库模块3.1插件接口模块设计插件接口模块是整个播放器的核心部分,它封装了对具体解码器的操作,从而在输入和输出模块之间搭建一座桥梁,确保数据的正常流动。插件接口模块主要提供了一下方法来控制解码器:3.1.1文件特性函数bool isfilesupported(const qstring&filename);通过检查文件的扩展名来确定待播放的文件是否被播放器支持,若是返回真,否则返回假。可识别的扩展名优asf、avi、mp2、mp3、mpeg、mpg、ogg、wav等。如果添加了新的解码器插件以后可以识别新的文件格式,只需要将其扩展名添加到此函数支持列表中即可。3.1.2获取文件信息函数const qsting&fileinfo();用于获取文件的各种信息并将结果保存到一个常量字符串中,便于其他函数调用。这些信息包括:播放时间、音频格式、音频比特率、音频通道、音频频率、视频格式、视频比特率、视频高度、视频宽度等。3.1.3读取音频采样函数bool audioreadsamples(short*output,int channels,long samples, long&samplesread,int);调用解码器对音频采样数据进行读取,是音频数据处理的核心部分。output表示待输出文件的指针,channels表示通道数,samples表示采样数,samplesread表示待读取采样数3.1.4视频帧函数 bool videareadscaledframe(unsigned char*output_rows,int int in_w, int in_h,int out_w,int out_h,colorformat fmt ,int);调用解码器对视频帧进行读取,是视频数据处理的和兴部分。参数output_rows表示输出列表的指针,in_w、in_h、out_w、out_h分别表示输入和输出的帧数据的宽度和高度,fmt表示采用的色彩模式,返回值用来判断执行是否成功。3.1.5音视频同步函数int sync(file*fp,int auindes,struct timeval*vtime);fp为打开的多媒体文件指针,vtime为当前正在播放的视频文件的帧头中提取的时间,auindex指出当前的音频帧计数,即当期播放到了第几帧。通过这些参数就可以计算出希望跳到的帧数和当前帧数的差值,然后根据这个差值将音频流向前(滞后)或向前(超前)跳即可。同时sync函数还会将此差值int反馈给音频解码器,让音频解码器修正数据流的时间戳,如此循环,从而达到较好的音视频同步效果。此函数的总体思想是在播放视频数据流的同时启动另一个线程,打开对应的音频数据流播放,然后再视频线程中来同步音频数据。此外还有插件初始化和注册函数void plugininit()、文件初始化函数void fileinit()、查找函数bool seek(long pos)、清空视频数据函数flushvideopackets()和清空音频数据函数flushaudiopackets()、获取下一数据包函数mediapacket*getanotherpacket(int stream)等,这里就不做详细介绍了。3.2解码库模块解码库模块的主要作用是为插件接口模块提供解码器,考虑到播放器的可移植性和扩展性,本系统采用了ffmpeg解码库。ffmpeg解码库是linux下的一个开源解码器集合,它支持多种音频和视频解码标准,还支持转文件格式、制作avi等,功能十分强大。可以在windows下是要使用ffshow插件,linux下的mplayer播放器都是使用ffmpeg解码库。解码库又包含解码器和分离器。解码器就是对音视频数据流进行解码的组件,分离器就是把文件流中的数据分离为音频数据流和视频数据流的组件,音频数据和视频数据是分开解码的,所以二者缺一不可。4嵌入式多媒体播放器系统的实现4.1数据流程的总体设计图2为系统数据流程:首先输入模块从数据流源(多媒体文件)读入数据,此时它将读入文件头,做一些基本的处理,如读出文件长度,获取此文件的编码类型、比特率,判断能否播放等;然后插件接口模块会调用分离器插件将多媒体切分为视频数据流和音频数据流;在经过视频fifo和音频fifo,排序处理;最后送入视、音频解码器调用相应的解码器进行解码,对于音频数据就会进行重采样,对于视频数据就会读取相应的帧,逐帧解码;之后经过采样的音频数据和经过渲染覆盖的视频数据进行音视频同步,再分别通过视、音频输出模块输出。这其中,数据的读入、分离、解码、输出都是通过qt提供的类库以多线程同时进行的,在解码的同时程序也在不断地将数据读入缓冲区并排序等待处理,以提高效率。输入模块的主要功能是将用户指定的多媒体文件读入。由于不同格式的多媒体文件需要调用不同的解码器才能正常打开,因此考虑到程序的模块化将实际的文件打开工作交给插件接口模块调用相应的解码器进行,输入模块只对文件进行一些基本的处理并对文件内容进行缓存,然后为插件接口模块输送原始数据流。用户首先通过图形界面选定待播放文件发出打开指令,这将会使输入模块接收到一个信号并通过用户界面传回的信息获得待播放文件的文件路径和文件名。接下来输入模块会检查文件路径是否合法、文件是否为空,之后会向插件接口模块发出信号,通知插件接口模块查找可用的解码器,为文件解码做好准备。下一步就是进行调用初始化函数init(),其具体过程下面会详细介绍,最后就是将工作移交给插件接口模块,让它调用对应的文件格式解码器的open()函数。输出模块的主要功能就是讲通过解码器解码之后的音频、视频数据送到输出设备(如lcd显示屏、扬声器)输出。根据输出内容的不同可以将输出模块划分为音频输出和视频输出两个子部分。这两个部分基本上是相互独立输出的,通过插件接口模块的同步控制让它们在输出时保持同步。视频输出和音频输出稍有不同,它利用qt/embedded可以将直接控制framebuffer的特性来输出视频数据。帧缓冲区是显卡上的内存,使用帧缓冲区可以提高绘图的速度和整体性能,与帧缓冲区有关的设备室/dev/vb0(主设备号29,此设备号0)。图2 系统数据流程4.2嵌入式音频视频同步设计本方法的基本思想是以视频为主媒体流,音频流为从媒体流,视频的播放速率保持不变,根据本系统时钟确定的实际显示时间,通过调整音频播放速度来达到音视频同步。整个系统的音视频同步数据流程见图3。首先选择一个本地系统时钟参考(lscr),要求本地系统时钟参考上的时间是线性递增的。然后将lscr分送到视频解码器和音频解码器,由这两个解码器根据各帧的pts值对照本地系统时钟参考产生各帧准确的显示或回放的时间。也就是说,生成输出数据流时依据本地参考时钟上的时间给没个数据块都打上时间戳(一般包括开始时间和结束时间)。在播放时,读取数据块上的时间戳,同时根据本地系统时间参考上的时间来安排播放。图3 音视频同步数据流程基于时间戳的播放过程中,仅仅对早到的或晚到的数据块进行等待或快速处理,往往是不够的。如果想要更加主动并且有效地调节播放性能,就需要引入反馈机制,也就是通过对比音视频的时间戳将当前数据流的播放状态反馈给上层的“源”。如果音频流滞后,就即时通知音频解码器加快音频流输出,但如果滞后太多,则直接将当前数据丢弃,直接跳到下一帧;如果视频流滞后,就通知音频解码器减慢音频输出速度等待视频流,如之后太多也直接进行跳帧。数据流首先通过分离器分解为视频数据流和音频数据流,然后经过对应的解码器,同时由本地系统时钟来进行时间戳控制;获得准确显示或回放时间以后进行时间戳比较;若同步则直接输出,不同步则进行音频跳帧或等待,直到同步后输出。5多媒体播放系统在pc端的实现5.1pc端环境的搭建本小结主要是介绍如何在centos 5.6环境中搭建qt开发环境,将qt_sdk_lin32_offline_v1_1_4_en.run软件包拷贝到centos双击即可开始安装。点击next,选择custom安装如图4所示,选择所需的开发工具,如图5所示,接着点击下一步即可,直到安装完成。图4选择安装方式图5开发工具选择5.2mplayer项目工程的建立与开发5.2.1mplayer工程的建立打开qt creator,单击文件,选择新建文件或工程,工程目录为/home /linux /mplayer,然后选择相应的模板,选择qt控件项目,选择qt gui应用,如图6所示图6 选择开发模板5.2.2mplayer实现原理先来考虑考虑如何为mplayer编写前端界面的问题。有两种思路,一种是把mplayer解剖,直接修改他里面的代码,这样我们做得界面就能够和mplayer一体了(当然也能够通过link mplayer用到的任何的库和.o文档,把他无缝的集成在程式里面);第二种方法就是mplayer所谓的slave模式。mplayer/home/linux/1.mp3-quiet-slave现在来探讨一下slave模式:所谓的slave模式,就是mplayer在运行过程中能够接收用户的输入命令行,具体支持哪些命令行,能够通过mplayer -input cmdlist这条命令来得到,在mplayer源码的slave.txt中也有对这些命令有详细的讲解。slave模式下工作的mplayer可以和系统的标准输入、输出进行信息交互。我们可以用linux c编程来完成对slave模式工作的mplayer进行控制和信息获取。如:mkfifo(“/tmp/fifo”,0777);可以使用popen()来打开mplayerfile* mp;mp=popen(“mplyer /home/linux/1.mp3 -quiet slave input file=/tmp/fifo,”r”);可以通过管道/tmp/fifo给mplayer发送命令,通过mp获取mplay的返回数据如:system(“echo ”mute 0” /tmp/fifo”);/写命令fgets(buf,1000,mp);/读取mplay返回数据而qt给我们提供了更方便的实现方法。通过定义一个qprocess对象调用已编译好的mplayer。qprocess *process = new qprocess();process-setprocesschannelmode(qprocess:mergedchannels);process-start(“mplayer ac mad xxxxx”);在命令中添加 -slave 和 -quiet就可以通过命令设置mplayer实现相应的功能。在mplayer源码中的,slave.txt中对这些命令有详细的讲解。process-start(“mplayer slave quiet ac mad xxxxx”);(1)暂停功能通过如下代码可以设置mplayer暂停。process-write(“pausen”);执行这段代码的时候如果是播放状态就会暂停,暂停状态时就会继续播放。(2)获取播放文件的总时间和当前播放进度执行下面代码时,mplayer将时间在标准输出显示。process-write(get_time_posn);process-write(get_time_lengthn);通过如下代码即可读出我们需要的信息:connect(process,signal(readyreadstandardoutput(),this,slot(back_message_slots();process有可读取的信息时,发出信号,在槽函数back_message_slots()中读取信息。void mplayer:back_message_slots()while(process-canreadline()qstring message(process-readline();/message即为读取的信息我们可以根据需要取我们要的信息如/文件总时间为:ans_length=23.00/当前时间为:ans_time_position=23.00(3)快进功能seek type seek to some place in the movie. 0 is a relative seek of +/- seconds (default). 1 is a seek to % in the movie. 2 is a seek to an absolute position of seconds.下面代码即可实现快进功能:process-write(“seek * 1n”);(4) 音量调节volume absincrease/decrease volume or set it to if abs is nonzero.下面代码即可实现快进功能:process-write(“volume -1n”);/音量减小process-write(“volume +1n”);/音量增加(5)静音功能mute value toggle sound output muting or set it to value when value = 0(1 = on, 0 = off).下面代码即可实现快进功能:process-write(mute 0n);/开启静音process-write(mute 1n);/关闭静音(6) 定位视频窗口通过上面的代码基本功能实现了,可是播放视频的时候发现又弹出一个窗口。并没有出现在我们的窗口里。如下代码即可时间窗口的定位。qstring common = mplayer -slave -quiet -ac mad -zoom movie/ + file_name + -wid + qstring:number(widget-winid(); process-start(common);红色部分实现窗口的定位。widget是一个qwidget对象。通过winid可以获得一个数字,-wid既将视频输出定位到widget窗体部件中。注意:-wid参数只在x11、directx和opengl中适用。5.2.3mplayer 界面ui搭建利用前面安装的designer搭建ui界面,并将其保存在/home/linux/mplayer/mplayer.ui界面搭建效果如图7。图7 mplayer界面搭建效果5.2.4mplayer 代码编写在/home/linux/mplayer/下创建mplayer.cpp、mplayer.h、main.cpp、image.qrc。其中main.cpp为主函数;mplayer.cpp为mplayer播放器的主程序代码,实现播放器的各项功能;mplayer.h为mplayer.cpp的头文件,其中包括mplayer.cpp中各个函数以及变量声明;image.qrc为资源文件,中间包括mplayer界面设计的界面元素相关链接信息。相关代码请查阅附件。5.2.5mplayer 工程编译与运行结果 如图8所示,选择编译或运行编译运行图8 工程的编译与运行运行结果如图9、图10、图11所示图9 播放效果图10 暂停效果图11 静音效果通过运行可以看出,mplayer相关功能已经实现,实现了多媒体的音视频播放功能。6总结从选课题开始,已经4个多月,这4个多月中,我们经历了风风雨雨。4个月的时间转眼即逝。这4个月中,我们边忙于找工作、实习,还要为我们的毕业设计查询资料、寻找方案。在这期间我们有茫然,有迷惑,也有豁然开朗的瞬间;又失败的痛楚,也有成功的甜蜜;有压力,也有轻松快哉。在毕业设计中,我们遇到了很多的难题,但是有我们的老师为我们指引方向和指导,也有同学的支持、鼓舞和帮助,终于使我克服了重重困难和阻碍,完成了这个设计的目标和任务。虽然它还离我心中的完美想去甚远,但是它得 成功使我认识到了自己的能力和相关的不足,使我能在未来弥补自身的不足。参考文献1 余雷.基于rfid电子标签的物联网物流管理系统j.微计算机信息,2006.2:233-2352 彭宣戈.一种嵌入式internet接口系统j.微计算机信息,2005.2: 8-9 3王亚民, 陈青, 刘畅生,等. 组态软件设计与开发m. 西安:西安电子科技大学出版社, 2003.4w.richard stevens, stephen a.rago, unix环境高级编程m, 第二版, 北京:人民邮电出版社,2006.致 谢附 录main.cpp#include #include mplayer.hint main(int argc, char *argv)qapplication app(argc, argv);mplayer player;player.show();return app.exec();mplayer.cpp#include mplayer.h#include #include mplayer:mplayer(qwidget *parent):qdialog(parent)setupui(this);isplay = true;issound = true;isstop = false;/playqicon icon_play;icon_play.addpixmap(qpixmap(qstring:fromutf8(images/pause_enabled.png), qicon:normal, qicon:off);pushbutton_2-seticon(icon_play);/stopqicon icon_stop;icon_stop.addpixmap(qpixmap(qstring:fromutf8(images/stop_enabled.png), qicon:normal, qicon:off);pushbutton_3-seticon(icon_stop);/rewardqicon icon_reward;icon_reward.addpixmap(qpixmap(qstring:fromutf8(images/reward_enabled.png), qicon:normal, qicon:off);pushbutton_4-seticon(icon_reward);/forwardqicon icon_forward;icon_forward.addpixmap(qpixmap(qstring:fromutf8(images/forward_enabled.png), qicon:normal, qicon:off);pushbutton_5-seticon(icon_forward);/soundqicon icon_sound;icon_sound.addpixmap(qpixmap(qstring:fromutf8(images/sound_enabled.png), qicon:normal, qicon:off);pushbutton-seticon(icon_sound);qicon icon_previous;icon_previous.addpixmap(qpixmap(qstring:fromutf8(images/previous_disabled.png), qicon:normal, qicon:off);pushbutton_6-seticon(icon_previous);qicon icon_next;icon_next.addpixmap(qpixmap(qstring:fromutf8(images/next_enabled.png), qicon:normal, qicon:off);pushbutton_7-seticon(icon_next);/设置按钮无边框pushbutton-setflat(true);pushbutton_2-setflat(true);pushbutton_3-setflat(true);pushbutton_4-setflat(true);pushbutton_5-setflat(true);pushbutton_6-setflat(true);pushbutton_7-setflat(true);/获得播放列表directory.setpath(./movie);files = directory.entrylist(qdir:allentries,qdir:time);file_name = files2;file_count = 2;label_3-settext(files2);horizontalslider-setpagestep(1);process = new qprocess(this);process-setprocesschannelmode(qprocess:mergedchannels);connect(pushbutton_2,signal(clicked(),this,slot(play_pause_slots();connect(pushbutton_3,signal(clicked(),this,slot(stop_slots();connect(pushbutton_4,signal(clicked(),this,slot(playerreward_slots();connect(pushbutton_5,signal(clicked(),this,slot(playerforward_slots();connect(pushbutton_6,signal(clicked(),this,slot(previous_slots();connect(pushbutton_7,signal(clicked(),this,slot(next_slots();/connect(horizontalslider,signal(valuechanged(int),this,slot(seek_slots(int);connect(spinbox,signal(valuechanged(int),this,slot(set_volume_slots(int);connect(pushbutton,signal(clicked(),this,slot(set_sound_slots();connect(process,signal(readyreadstandardoutput(),this,slot(back_message_slots();/process-start(mplayer -slave -quiet -ac mad 2.avi);/add -wid qwidget-winid();qstring common = mplayer -slave -quiet -ac mad -zoom movie/ + file_name + -wid + qstring:number(widget-winid(); process-start(common);spinbox-setvalue(40);timer = new qtimer(this);connect(timer,signal(timeout(),this,slot(get_time_slots();timer-start(1000);void mplayer:play_pause_slots()if(!isplay)if(isstop)file_name = filesfile_count;qstring common = mplayer -slave -quiet -ac mad -zoom movie/ + file_name + -wid + qstring:number(widget-winid(); process-start(common);qicon icon_stop;icon_stop.addpixmap(qpixmap(qstring:fromutf8(images/stop_enabled.png), qicon:normal, qicon:off);pushbutton_3-seticon(icon_stop);isstop = false;elseprocess-write(pausen);qicon icon_play;icon_play.addpixmap(qpixmap(qstring:fromutf8(images/pause_enabled.png), qicon:normal, qicon:off);pushbutton_2-seticon(icon_play);isplay = true;elseqicon icon_pause;icon_pause.addpixmap(qpixmap(qstring:fromutf8(images/play_enabled.png), qicon:normal, qicon:off);pushbutton_2-seticon(icon_pause);isplay = false;process-write(pausen);void mplayer:stop_slots()if(!isstop)process-write(quitn);qicon icon_pause;icon_pause.addpixmap(qpixmap(qstring:fromutf8(images/play_enabled.png), qicon:normal, qicon:off);pushbutton_2-seticon(icon_pause);isplay = false;qicon icon_stop;icon_stop.addpixmap(qpixmap(qstring:fromutf8(images/stop_disabled.png), qicon:normal, qicon:off);pushbutton_3-seticon(icon_stop);isstop = true;label-settext(00:00:00);label_2-settext(00:00:00);void mplayer:previous_slots()if(file_count 2)if(file_count = (files.size()-1)qicon icon_next;icon_next.addpixmap(qpixmap(qstring:fromutf8(images/next_enabled.png), qicon:normal, qicon:off);pushbutton_7-seticon(icon_next);process-write(quitn);process = new qprocess(this);connect(process,signal(readyreadstandardoutput(),this,slot(back_message_slots();file_count-;if(!isstop)file_name = filesfile_count;qstring common = mplayer -slave -quiet -ac mad -zoom movie/ + file_name + -wid + qstring:number(widget-winid(); process-start(common);if(file_count = 2)qicon icon_previous;icon_previous.addpixmap(qpixmap(qstring:fromutf8(images/previous_disabled.png), qicon:normal, qicon:off);pushbutton_6-seticon(icon_previous);label_3-settext(filesfile_count);void mplayer:next_slots()if(file_count seticon(icon_previous);process-write(quitn);process = new qprocess(this);connect(process,signal(readyreadstandardoutput(),this,slot(back_message_slots();file_count+;if(!isstop)file_name = filesfile_count;qstring common = mplayer -slave -quiet -ac mad -zoom movie/ + file_name + -wid + qstring:number(widget-winid(); process-start(common);if(file_count = (files.size()-1)qicon icon_next;icon_next.addpixmap(qpixmap(qstring:fromutf8(images/next_disabled.png), qicon:normal, qicon:off);pushbutton_7-seticon(icon_next);label_3-settext(filesfile_count);void mplayer:seek_slots(int seek_num)qdebug()state() = qprocess:running )process-write(qstring(seek + qstring:number(qmin(seek_num,100) + 1n).toascii();void mplayer:get_time_slots()if(isplay)process-write(get_time_posn);process-write(get_time_lengthn);void mplayer:set_volume_slots(int volume)qdebug()write(qstring(volume + + qstring:number(volume) + n).toascii();/process-write(qstring(volume +1n).toascii();void mplayer:set_sound_slots()if(issound)process-write(mute 1n);qicon icon_sound;icon_sound.addpixmap(qpixmap(qstring:fromutf8(images/nosound_enabled.png), qicon:normal, qicon:off);pushbutton-seticon(icon_sound);issound = false;elseprocess-write(mute 0n);qicon icon_sound;icon_sound.addpixmap(qpixmap(qstring:fromutf8(images/sound_enabled.png), qicon:normal, qicon:off)
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 教育地产项目的生态环境保护策略
- 广东省梅县东山中学、揭阳一中、汕头一中、潮州金中四校2024-2025学年高一下学期期中联考物理试题(含解析)
- 智慧安防科技为城市安全保驾护航
- 2025年广东省物理中考学业水平模拟练习卷
- 2024-2025学年度高二第二学期期中考试答案
- 企业培训中智慧教室的设计与创新
- 探索教育心理学在解决学生焦虑问题中的实践
- 敏感肌洁面慕斯企业制定与实施新质生产力项目商业计划书
- 【暑假打卡计划】2025年八年级英语下册复习篇 第1天Unit 5(仁爱版)
- 风车景观旅游区行业跨境出海项目商业计划书
- 足外伤个案护理
- 单位食堂配送菜合同协议书
- 慢性非传染性疾病综合防控示范区申报考评细则培训课件
- 浙江省城镇生活垃圾分类标准
- 语言学纲要期末复习考点(完整)
- 2024年广西中考道德与法治试卷真题(含答案解析)
- DL-T+796-2012风力发电场安全规程
- 2024中考地理一轮复习专题1地球和地球仪(讲义)(原卷版)
- DL-T-1642-2016环形混凝土电杆用脚扣
- SF-36生活质量调查表(SF-36-含评分细则)
- 畜禽生产概论-形考任务3-国开(HB)-参考资料
评论
0/150
提交评论