一、PC环境搭建
主机环境:Red Hat Enterprise Linux 5.0
交叉编译工具:gcc-3.4.5-glibc-2.3.6
主机编译工具:gcc-4.1.2
1、主机端安装mplayer
将“项目代码/mplay源码”目录下的MPlayer-1.0rc2.tar.bz2、libmad-0.15.1b.tar.gz(1个mp3解码库)拷贝到linux系统中,如:/home/linux/mplayer目录下
安装libmad-0.15.1b.tar.gz
- #tar xvfz libmad-0.15.1b.tar.gz
- #cd libmad-0.15.1b
- #./configure
- #make
- #mkdir /lib/lib
- #mkdir /lib/include
- #cp mad.h /lib/include
- #cp .libs/libmad.a /lib/lib
- l 安装mplayer
- #tar xvfj MPlayer-1.0.rc2.tar.bz2
- #cd MPlayer-1.0rc2
- #./configure --with-extraincdir=/lib/include --with-extralibdir=/lib/lib
- #make
- #make install
此时可以试着播放一下mp3、avi等文件了
- # mplayer -ac mad 1.mp3
- # mplayer -ac mad 2.avi
2、安装、移植qtopia-4.2.0
注:需要先按照5.2节将tslib按照好,将“项目代码/qtopia源码”目录下的qtopia-opensource-src-4.2.0.tar.gz拷贝到linux系统中,如:/home/linux/Qtopia目录下
- # tar zxvf qtopia-opensource-src-4.2.0.tar.gz
- # mv qtopia-opensource-4.2.0 source
- # mkdir target //创建在source同级目录下创建目录target
修改源码包
- # cd source
- # cd src/libraries/qtopiabase/
- # cp custom-linux-cassiopeia-g++.h custom-linux-arm-g++.h
- # cp custom-linux-cassiopeia-g++.cpp custom-linux-arm-g++.cpp
修改时区信息
- # vi src/libraries/qtopia/qtimezone.cpp
- 将114行的 /usr/share/zoneinfo/ 改为/Qtipia/zoneinfo/ ,保存退出。
- # vi src/settings/systemtime/settime.cpp
- 将318行的 /usr/share/zoneinfo/ 改为/Qtipia/zoneinfo/ ,保存退出。
裁减Qtopia core的库(下列操作后在屏幕上会出现一个光标,否则没有光标。根据需求配置)
- # vi qtopiacore/qconfig-qpe.h
首先注释掉关于鼠标光标的宏定义,让程序运行时,触摸屏中央有光标出现:
- // Qtopia Core
- /*
- #ifndef QT_NO_QWS_CURSOR
- # define QT_NO_QWS_CURSOR
- #endif
- */
- /*
- #ifndef QT_NO_QWS_MOUSE
- # define QT_NO_QWS_MOUSE
- #endif
- #ifndef QT_NO_QWS_MOUSE_AUTO
- # define QT_NO_QWS_MOUSE_AUTO
- #endif
- */
其它宏定义根据需要进行注释。
#p#
保存后将qconfig-qpe.h拷贝到global目录。
- # cp qtopiacore/qconfig-qpe.h qtopiacore/qt/src/corelib/global/qconfig-qpe.h (必须进行的操作)
注释掉其他文件里的QT_NO_QWS_CURSOR的定义
- # vi qtopiacore/qt/src/corelib/global/qfeatures.h
注释掉如下内容:
- /*
- #if !defined(QT_NO_QWS_CURSOR) && (defined(QT_NO_CURSOR))
- #define QT_NO_QWS_CURSOR
- #endif
- */
保存退出。
- # vi qtopiacore/qt/src/corelib/global/qglobal.h
注释掉以下内容:
- //# define QT_NO_QWS_CURSOR
- #vim qtopiacore/qt/tools/qvfb/qvfbshmem.cpp
注释掉asm/page.h
- //#include <asm/page.h>
- #vim qtopiacore/qt/tools/qvfb/qvfbmmap.cpp
注释掉asm/page.h
- //#include <asm/page.h>
并修改如下内容
- unsigned char *data;
- uint data_offset_value = sizeof(QVFbHeader);
- if (data_offset_value % PAGE_SIZE)
- data_offset_value += PAGE_SIZE - (data_offset_value % PAGE_SIZE);
为:
- unsigned char *data;
- uint data_offset_value = sizeof(QVFbHeader);
- const int page_size = getpagesize();
- if (data_offset_value % page_size)
- data_offset_value += page_size - (data_offset_value % page_size);
- # vim src/libraries/qtopiabase/qmemoryfile_unix.cpp +128
修改:
- f = ::open(tmpFile.toLatin1(), O_CREAT | O_WRONLY);
为:
- f = ::open(tmpFile.toLatin1(), O_CREAT | O_WRONLY ,0777);
修改交叉工具
- #vim qtopiacore/qt/mkspecs/qws/linux-arm-g++/qmake.conf
将文件中的arm-linux-***全部修改为arm-softfloat-linux-gnu-**
这样做的前提是我的交叉工具链是arm-softfloat-linux-gnu,如果你的是arm-linux就不用改了。
#p#
生成Makefile
#cd ../target //为了不破坏源码,选择在此目录下配置、编译源码
- #../source/configure -release -image /Qtopia -prefix /Qtopia -xplatform linux-arm-g++
- -arch arm -no-qvfb -displaysize 320x240 -no-modem -extra-qtopiacore-config "-release
- -xplatform qws/linux-arm-g++ -embedded arm -qconfig qpe -depths 4,8,16,32
- -qt-sql-sqlite -no-mouse-linuxtp -qt-mouse-tslib -I/home/linux/tslib/include
- -L/home/linux/tslib/lib " 2>../configureERR.txt
注意:这里/Qtopia是***Qtopia的安装路径,安装到主机的某个路径下,最终这个路径和目标板上的路径必须一致。
主要配置选项说明如下:
- -xplatform linux-arm-g++ -arch arm
目标平台为arm-linux,体系结构为arm。
- -no-qvfb
目标平台已支持framebuffer,因而不使用虚拟帧缓冲。
- -extra-qtopiacore-config
为Qtopia core 配置选项。
- -xplatform qws/linux-arm-g++ -embedded arm
目标平台编译配置文件使用qtopiacore/qt/mkspecs/qws/linux-arm-g++目录下的配置文件,嵌入式平台为arm。
- -qconfig qpe
使用配置文件qconfig-qpe.h,若使用qconfig-large.h配置文件,则使用-qconfig large选项。
- -qt-sql-sqlite
数据库支持Sqlite。
- -qt-kbd-usb
键盘支持usb协议。
- -no-mouse-linuxtp -qt-mouse-tslib
- -I/home/linux/tslib/include -L/home/linux/tslib/lib
触摸屏协议不支持linuxtp,支持tslib,并在后面添加上刚才编译的tslib的头文件和库。
- ../qtopiaconfigureERR.txt
***将配置过程中的错误输出到qtopiaconfigureERR.txt文件中。
编译
- #make
- #make install
将安装和的目录考到nfsroot目录下
- #cp /Qtopia /rootfs -a
3、熟悉主机开发环境
提供给PC端的开发工具
上面的qtopia编译安装完成后,会在咱们前面创建的target目录下生成很多开发工具。
先看一下供主机端使用的工具
- [root@localhost bin]# pwd
- /home/linux/Qtopia/target/qtopiacore/host/bin
- [root@localhost bin]# ls
- assistant linguist lupdate qmake rcc uic
- designer lrelease moc qvfb templates uic3
如果系统以前有其它qt开发工具,把环境变量修改一下,保证它们不要和我们这几个工具冲突。下面可以试一下你的designer了。
- #./designer
二、在PC端实现基于qt前端的mplayer播放器
创建工程目录/home/linux/mplayer
1、搭建ui界面
利用前面安装的designer搭建ui界面,并将其保存至/home/linux/mplayer/mplayer.ui
- #./designer
圆角矩形标注: 加了一个widget,留作mplayer的播放区
2、编写程序
在/home/linux/mymplayer/下创建mplayer.cpp、mplayer.h、main.cpp 、image.qrc
Main.cpp
- #include <QApplication>
- #include "mplayer.h"
- int main(int argc, char **argv)
- {
- QApplication app(argc, argv);
- MPlayer player; //实例最终的MPlayer类
- player.show(); //显示界面
- return app.exec(); //运行程序
- }
- mplayer.h
- #ifndef _MPLAYER_H
- #define _MPLAYER_H
- #include <QIcon>
- #include <QProcess>
- #include <QTimer>
- #include <QStringList>
- #include <QDir>
- #include <QTime>
- #include <QString>
- #include "ui_mplayer.h"
- class MPlayer:public QDialog,private Ui_Dialog
- {
- Q_OBJECT
- public:
- MPlayer(QWidget *parent = 0);
- public:
- QTime int_to_time(int);
- public slots:
- void play_pause_slots(); //暂停
- void stop_slots(); //停止
- void previous_slots(); //上一曲
- void next_slots(); //下一曲
- void seek_slots(int);
- void get_time_slots(); //得到播放时间
- void set_volume_slots(int); //设置音量
- void set_sound_slots(); //静音
- void playerReward_slots(); //快退
- void playerForward_slots(); //快进
- void back_message_slots(); //更新显示信息
- private:
- QProcess *process;
- QStringList files;
- QDir directory;
- int file_count;
- QString file_name;
- bool isPlay;
- bool isSound;
- bool isStop;
- QTimer *timer;
- int file_length;
- int curr_time;
- };
- #endif
#p#
mplayer.cpp
- #include "mplayer.h"
- #include <QDebug>
- #include <unistd.h>
- MPlayer::MPlayer(QWidget *parent):QDialog(parent)
- {
- setupUi(this); //初始化界面
- isPlay = true;
- isSound = true;
- isStop = false;
- /************************为按键添加图标**************************/
- //play
- QIcon icon_play;
- icon_play.addPixmap(QPixmap(QString::fromUtf8("images/pause_enabled.png")), QIcon::Normal, QIcon::Off);
- pushButton_2->setIcon(icon_play);
- //stop
- QIcon icon_stop;
- icon_stop.addPixmap(QPixmap(QString::fromUtf8("images/stop_enabled.png")), QIcon::Normal, QIcon::Off);
- pushButton_3->setIcon(icon_stop);
- //reward
- QIcon icon_reward;
- icon_reward.addPixmap(QPixmap(QString::fromUtf8("images/reward_enabled.png")), QIcon::Normal, QIcon::Off);
- pushButton_4->setIcon(icon_reward);
- //forward
- QIcon icon_forward;
- icon_forward.addPixmap(QPixmap(QString::fromUtf8("images/forward_enabled.png")), QIcon::Normal, QIcon::Off);
- pushButton_5->setIcon(icon_forward);
- //sound
- QIcon 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 = files[2]; //文件0和1为 ”.” ”..”,所以从文件2开始播放
- file_count = 2;
- label_3->setText(files[2]);
- /*************************初始化进度条及QProcess类**************/
- 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可以读到Mplayer的返回信息时,产生readyReadStandardOutput()信号
- //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()); //这里的widget是ui中MPlayer的显示区
- process->start(common); //开始运行程序
- spinBox->setValue(40);
- timer = new QTimer(this);
- connect(timer,SIGNAL(timeout()),this,SLOT(get_time_slots()));
- //定时获取MPlayer的时间信息
- timer->start(1000); //启动定时器 1秒timeout 1次
- }
- void MPlayer::play_pause_slots()
- {
- if(!isPlay)
- {
- if(isStop)
- {
- file_name = files[file_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;
- }
- else
- {
- process->write("pause ");
- }
- QIcon icon_play;
- icon_play.addPixmap(QPixmap(QString::fromUtf8("images/pause_enabled.png")), QIcon::Normal, QIcon::Off);
- pushButton_2->setIcon(icon_play);
- isPlay = true;
- }
- else
- {
- QIcon 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("pause ");
- }
- }
- void MPlayer::stop_slots()
- {
- if(!isStop)
- {
- process->write("quit ");
- 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("quit ");
- process = new QProcess(this);
- connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(back_message_slots()));
- file_count--;
- if(!isStop)
- {
- file_name = files[file_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(files[file_count]);
- }
- }
- void MPlayer::next_slots()
- {
- if(file_count < (files.size()-1))
- {
- if(file_count == 2)
- {
- QIcon icon_previous;
- icon_previous.addPixmap(QPixmap(QString::fromUtf8("images/previous_enabled.png")), QIcon::Normal, QIcon::Off);
- pushButton_6->setIcon(icon_previous);
- }
- process->write("quit ");
- process = new QProcess(this);
- connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(back_message_slots()));
- file_count++;
- if(!isStop)
- {
- file_name = files[file_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(files[file_count]);
- }
- void MPlayer::seek_slots(int seek_num)
- {
- qDebug()<<seek_num;
- if(process && process->state() == QProcess::Running )
- {
- process->write(QString("seek " + QString::number(qMin(seek_num,100)) + "1 ").toAscii());
- }
- }
- void MPlayer::get_time_slots()
- {
- if(isPlay)
- ]{
- p
- rocess->write("get_time_pos ");
- process->write("get_time_length ");
- }
- }
- void MPlayer::set_volume_slots(int volume)
- {
- qDebug()<<volume;
- process->write(QString("volume +" + QString::number(volume) + " ").toAscii());
- //process->write(QString("volume +1 ").toAscii());
- }
- void MPlayer::set_sound_slots()
- {
- if(isSound)
- {
- process->write("mute 1 ");
- QIcon icon_sound;
- icon_sound.addPixmap(QPixmap(QString::fromUtf8("images/nosound_enabled.png")), QIcon::Normal, QIcon::Off);
- pushButton->setIcon(icon_sound);
- isSound = false;
- }
- else
- {
- process->write("mute 0 ");
- QIcon icon_sound;
- icon_sound.addPixmap(QPixmap(QString::fromUtf8("images/sound_enabled.png")), QIcon::Normal, QIcon::Off);
- pushButton->setIcon(icon_sound);
- isSound = true;
- }
- }
- void MPlayer::playerReward_slots()
- {
- //bool ok;
- //int m=moviePosition.toInt(&ok);
- if (process && process->state()==QProcess::Running && !isPlay)
- {
- //QString cmd="seek "+QString::number(qMax(m-10,0))+" 1 ";
- //process->write(cmd.toAscii());
- qDebug()<<"Reward";
- }
- }
- void MPlayer::playerForward_slots()
- {
- // groupBox->setVisible(false);
- //bool ok;
- //int m=moviePosition.toInt(&ok);
- /* if (process && process->state()==QProcess::Running && !isPlay)
- {
- //QString cmd="seek "+QString::number(qMin(m+10,100))+" 1 ";
- //process->write(cmd.toAscii());
- qDebug()<<"Forward";
- }*/
- }
- void MPlayer::back_message_slots()
- {
- while(process->canReadLine())
- {
- QString message(process->readLine());
- QStringList messagemessage_list = message.split("=");
- if(message_list[0] == "ANS_TIME_POSITION")
- {
- curr_time = message_list[1].toDouble();//toInt();
- QTime time = int_to_time(curr_time);
- label->setText(time.toString("hh:mm:ss"));
- horizontalSlider->setValue(100 * curr_time / file_length);
- }
- else if(message_list[0] == "ANS_LENGTH")
- {
- file_length = message_list[1].toDouble();//toInt();
- QTime time = int_to_time(file_length);
- label_2->setText(time.toString("hh:mm:ss"));
- }
- }
- }
- QTime MPlayer::int_to_time(int second)
- {
- int sec = 0, min = 0, hour = 0;
- QTime time;
- if(second < 60)
- {
- sec = second;
- min = 0;
- hour = 0;
- }
- if(second >= 60 && second < 3600)
- {
- sec = second % 60;
- min = second / 60;
- hour = 0;
- }
- if(second >= 3600)
- {
- sec = second % 60;
- min = (second / 60) % 60;
- hour = second / 3600;
- }
- time.setHMS(hour,min,sec);
- return time;
- }
- image.qrc
- <RCC>
- <qresource prefix="images" >
- <file>images/player_play.png</file>
- <file>images/player_stop.png</file>
- <file>images/player_pause.png</file>
- <file>images/play_enabled.png</file>
- <file>images/pause_enabled.png</file>
- <file>images/reward_enabled.png</file>
- <file>images/forward_enabled.png</file>
- <file>images/stop_enabled.png</file>
- <file>images/sound_enabled.png</file>
- <file>images/nosound_enabled.png</file>
- <file>images/previous_enabled.png</file>
- <file>images/previous_disabled.png</file>
- <file>images/next_enabled.png</file>
- <file>images/next_disabled.png</file>
- </qresource>
- </RCC>
#p#
3、编译工程
拷贝qmake到当前工程目录下
- #cp /home/linux/Qtopia/target/qtopiacore/host/bin/qmake ./
生成项目文件、
- #qmake –project
- 生成Makefile
- #qmake
编译
- #make
成功后,可以生成mplayer可执行程序
建立movie和images
- #mkdir movie
- #mkdir images
- [root@localhost mplayer]# ls movie/
- 1.mp3 2.avi 3.avi 4.avi 5.avi
- [root@localhost mplayer]# ls images
- forward_enabled.png nosound_enabled.png player_play.png reward_enabled.png
- images pause_enabled.png player_stop.png sound_enabled.png
- next_disabled.png play_enabled.png previous_disabled.png stop_disabled.png
- next_enabled.png player_pause.png previous_enabled.png stop_enabled.png
运行程序
- [root@localhost mplayer]#./mplayer
【编辑推荐】