Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2567919
  • 博文数量: 315
  • 博客积分: 3901
  • 博客等级: 少校
  • 技术积分: 3640
  • 用 户 组: 普通用户
  • 注册时间: 2011-05-08 15:32
个人简介

知乎:https://www.zhihu.com/people/monkey.d.luffy Android高级开发交流群2: 752871516

文章分类

全部博文(315)

文章存档

2019年(2)

2018年(1)

2016年(7)

2015年(32)

2014年(39)

2013年(109)

2012年(81)

2011年(44)

分类: C/C++

2011-12-15 16:22:08

  我负责的就是一个界面布局,嵌入MPlayer播放器,时钟啊,图片滚动啊之类的就行了。最后在开发板上去跑这个程序,当然在PC机环境下测试好自己的程序后,直接烧到开发板肯定不行的,那么我们就需要交叉编译Qt程序,生成.bin可执行文件,然后在去编译一个MPlayer播放器,将他们同时烧过去,当然Qt程序需要的目录啊,图片啊,文件啊这些东西要在开发板处建立好;
  这里我们采用的是nfs挂在文件系统,所以我们只需要在rootfs的nfs共享目录下的linux文件系统中放入相关的程序和文件就行了,很方便于修改和开发。
  在做程序的过程中还是遇到了很多问题,比如进程的时候,因为涉及到嵌入MPlayer播放器,涉及到进程的相关控制,设计到开发板的分层显示功能,所以挺复杂的,但是在老师的帮助下,其实老师的功能很大了,因为很多地方我们都不懂,而且时间就三四天,想要完整的做完几乎是不可能的。所以最后结果也不是很理想,不过框架基本做完了。还算是有点收获的,只是结果不太令人满意,以后需要用心的去琢磨和学习知识,扎实很重要。
   Qt和MPlayer部分的编译在另一篇文章中已经说说明了,需要自己动手实践后才有体会,因为过程中可能会遇到很多不同的问题。

   下面我主要就是说下在代码(arm版本的)中主要的部分,因为相信很多人对QT已经很好了,我知识个菜鸟:

//主窗体

#include "mainwidget.h"
#include "clock.h"
#include "pic.h"
#include "message.h"
#include "mplayer.h"

MainWidget::MainWidget(QWidget *parent)
    :QWidget(parent)
{

    this->setAutoFillBackground(true);//1s step
    QPalette palette;//2s step
    palette.setBrush(QPalette::Background, QBrush(QPixmap("backt.jpg")));
    this->setPalette(palette);//3s step


    label_pl = new QLabel(this);
    label_pr = new QLabel(this);
   
    pm = new QMovie("logo.gif");
    label_pl->setMovie(pm);
    label_pr->setMovie(pm);
    pm->start();


    label_pl->setGeometry(0, 0, 100, 100);
    label_pr->setGeometry(500, 0, 100, 100);


    label_clk = new QLabel(this);
    pix_clk = new QPixmap("clk.jpg");
    
    label_wether = new QLabel(this);
    pix_wether = new QPixmap("weather/light.png");
    
    label_clk->setGeometry(620, 10, 180, 80);
    label_clk->setPixmap(pix_clk->scaled(label_clk->width(), label_clk->height()));

    label_wether->setGeometry(666, 110, 100, 90);
    label_wether->setPixmap(pix_wether->scaled(label_wether->width(), label_wether->height()));

    Clock *clk = new Clock(this); 
    clk->setGeometry(625, 20, 150, 50); 

    Pic *pic = new Pic(this);
    pic->show();

    Message *msg = new Message(this);
    msg->show();

    MPlayer *mplayer = new MPlayer(this);
    mplayer->show();

    this->setGeometry(0, 0, 800, 480);
}

 
//相关的文件夹目录  

 log 目录下
message.txt  //一旦发现该目录下的此文件更新,

就重新加载滚动的文字;

pic.log // 保存当前图片的信息
 
video.log //保存当前播放视频的信息

 picture 目录下

       
各种图片,用于广告图片显示,一旦发现有更新,

也是立即刷新图片列表。
  
   
 video 目录下

视频文件 和 playlist.lst播放列表 //一旦发现有

新的视频更新或者删除,重新读取视频播放列表。

 
 weather 目录,存放当天天气信息,本来打算用编程来读取

网络天气的,发现不行,最后放弃了,不想放弃的。呵呵!(后来有在网络达人的分享下搞定了。改天贴上)

  当前工作目录下还有一个tmp目录,是文件系统有的,然后

我在其中创建了管道cmd(用mkfifo cmd),管道的作用是可以接受来自用户的对于

MPlayer播放器的控制命令,命令就是通过这个管道传送的,

可以播放,暂停,开始等命令。


   //相关界面和控制技巧


  MPlayer::MPlayer(QWidget *parent)
    :QWidget(parent)
{
//刷新开发板屏幕
    system("cat /dev/zero >/dev/fb0 2>/dev/null");

    //创建一个进程,用于执行mplayer
    process = new QProcess(parent);


//创建一个窗体,用于放置mplayer
    renderTarget = new QWidget(this);   
    renderTarget->setGeometry(0, 100, 620, 380);
    renderTarget->setAutoFillBackground(true);
  
    QPalette palette = renderTarget->palette();

    palette.setColor(QPalette::Background, Qt::black);
    renderTarget->setPalette(palette);

//创建一个监视器,用于监视目录和目录下文件的变化
    fileWatcher = new QFileSystemWatcher(this);
    fileWatcher->addPath("video/");

//连接目录变化的槽,一旦变化就重新播放视频
    connect(fileWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(play_video()));
   
    QString common;

//构造一个mplayer播放的字符串,注意如果是播放列表的话,需要放在视频目录下,因为他会自动加上一个./video/目录,所以这样才可以,而且文件中存名字就好了,目录在播放时自动添加,这应该是设计好的
    common = QString("%1%2%3%4%5%6%7%8%9").arg("./mplayer ").arg("-playlist ./video/playlist.lst -loop 0").arg(" -x ").arg(QString::number(renderTarget->width())).arg(" -y ").arg(renderTarget->height()).arg(" ").arg(" -geometry 0:100").arg(" -slave >/dev/null 2>&1");
    

    process->start(common);
   
//如果有可读信息就读出来,也就是可以读出当前播放信息,然后拆分出需要的信息,并且写入日志文件
    connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(back_message_slots()));
}

 //滚动文字
#include
#include
#include

#include "message.h"

Message::Message(QWidget *parent)
    :QLabel(parent)
{
    label = new QLabel(parent); 
    QPixmap *pic = new QPixmap("txt.jpg");
    label->setGeometry(100, 8, 400, 80);
    label->setPixmap(pic->scaled(label->width(),label->height()));
    
    label_txt = new QLabel(parent);
  
    //Font's size setting;
    str = str.fromLocal8Bit("快乐男孩!");
    label_txt->setFont(QFont("wenquanyi", 20, QFont::Bold));

    //Font's color setting;
    QPalette pe_txt;
    pe_txt.setColor(QPalette::WindowText,Qt::blue);
    label_txt->setPalette(pe_txt);
   

    QTimer *timer2 = new QTimer(this);
    connect(timer2, SIGNAL(timeout()), this, SLOT(show_txt()));
    timer2->start(20);
    
    fileWatcher = new QFileSystemWatcher(this);
    fileWatcher->addPath("log/");
    connect(fileWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(set_txt()));
    set_txt();
}

void Message::set_txt()
{
    QFile file("log/message.txt");
    
    if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) // /r/n ---> /n
        return;
   
   char buffer[2048];
   qint64 lineLen = file.readLine(buffer, sizeof(buffer));
   if(lineLen != -1)
   {
        str = str.fromLocal8Bit(buffer);
        //qDebug() << str; 
   }
   file.close();
}

void Message::show_txt()
{
#if 1 
    static int i = 380;
    
    if(i == 110) i = 380;

    label_txt->setText(str);
    label_txt->setGeometry(i--, 5, 300, 100);
#endif
}

//滚动图片
#include

#include "pic.h"

Pic::Pic(QWidget *parent)
    :QLabel(parent)
{
    flag = 1; //for picture moving

    label = new QLabel(parent);
    label->setGeometry(620, 200, 180, 200);
    

    timer = new QTimer(this);
    timer_lb = new QTimer(this);
   
    fileWatcher = new QFileSystemWatcher(this);
    fileWatcher->addPath("picture/");
    
    connect(fileWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(build_pic()));
    build_pic();
    
    connect(timer, SIGNAL(timeout()), this, SLOT(show_pic()));
    show_pic();
    timer->start(30000);
   
    connect(timer_lb, SIGNAL(timeout()), this, SLOT(update_label()));
    timer_lb->start(1000);
}

void Pic::build_pic()
{
    //qDebug() << "build pic" <
    QDir *dir = new QDir("picture");

    QStringList qst;

    qst << "*.jpg";

    qst = dir->entryList(qst);
    
    pic_count = qst.count();

     for(int i = 0; i < qst.count(); ++i)
     {
         QString string;
         char buf[50];
         strcpy(buf,"picture/");
         string = strcat(buf, qst.at(i).toLocal8Bit().constData());
         pic[i] = new QPixmap(string);
         
         strcpy(name_list[i], string.toLocal8Bit().data());
         //qDebug() << name_list[i]; 
    }
}

void Pic::show_pic()
{
    static int i = 0;

    if(i == pic_count)
        i = 0;

    //before showing, save current picture's information to pic.log;
    QFileInfo info(name_list[i]); 
    
    //获取图片文件信息,对视频不管用
    qint64  size = info.size();
    QDateTime created = info.created();
    QDateTime lastModified = info.lastModified();
    QDateTime lastRead = info.lastRead();

    QString str;
    
    str = QString("%1\n%2 Bytes\n%3\n%4\n%5\n").arg(name_list[i]).arg(QString::number(size, 10)).arg(created.toString()).arg(lastModified.toString()).arg(lastRead.toString());
    //qDebug() << str;
    
    QFile file("log/pic.log");

    if(!file.open(QFile::WriteOnly | QFile::Truncate))
        return;
   
    QTextStream ts(&file);
    ts << str;

    file.close();
    
    //测试
    //qDebug() << name_list[i]; 
    //qDebug() << QString::number(size, 10) << "Bytes"; 
    //qDebug() << created.toString(); 
    //qDebug() << lastModified.toString(); 
    //qDebug() << lastRead.toString(); 


    label->setPixmap(pic[i++]->scaled(label->width(), label->height()));
}

void Pic::update_label()
{
   static int j = 200;
   
   if(1 == flag)
        j = j + 20;
   else
        j = j - 20;

    if(280 == j)
        flag = -1;
    if(200 == j)
        flag = 1;
    
    label->setGeometry(620, j, 180, 200);
}

 其实写这些东西可能没有什么用,只是表露以下思维方式,可能比较低效,但还是想写写,管他的了。

  至于主函数这里就不怎么说了,因为要融合lcd.h文件,就是关于屏幕的一些设置,分层显示的一些东西,不是很了解,老师给了源码,就拿来用了。最后能在开发板上跑起来。


 然后组员也都把服务器写好了,就差CGI程序和C服务器的结合,当点击网页的控制按钮提交信息后,就可以通过CGI程序获取文本框信息,或是上传图片,或是上传文字,当然还有按钮的值,然后判断是哪中按钮按下,程序根据判断执行不同的命令,发送不同的命令,终端收到相关命令后执行相应的操作就行了。

比如CGI程序获取了暂停mplayer播放的命令,就直接发送命令到开发板的服务器端,那个C程序就根据命令,向tmp/cmd管道写入相应命令就行了。

    所以我的开发板需要同时运行三个进程,Qt+mplayer+服务器程序。大体就这样。

   一个界面简单展示效果:

阅读(7008) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~