用qt的label控件显示mjpg-streamer中的视频画面

###stitip项目中需要用Qt编写一个带界面的实现实时监控的程序,所以准备学习Qt的开发,本文档记录的是是学习Qt过程中的笔记,方便自己复习使用。###

 

2016.9.2

目标:今天想要实现在label中显示自己定义的一张图片,并且自动将大小设置为图片的宽和高。

一、直接添加图片

1.参考Qt的帮助文档,可支持的类型,即可以直接读取并显示的格式有BMPGIFJPGJPEGPNGTIFFPBMPGMPPMXBMXPM

2.显示图片步骤:

先打开一个图像;将图像文件加载进QImage对象中;再用QPixmap对象获得图像;最后用QLabel选择一个QPixmap图像对象显示。

这是要插入的图片:

 用qt的label控件显示mjpg-streamer中的视频画面_第1张图片

 

代码如下(在这之前需要在界面里添加一个Qlabel控件,对象名为label

QString filename(“F:\\Study\\junior\\Qt\\door\\1.jpg”);
        QImage* img=new QImage;
        if(! ( img->load(filename) ) ) //加载图像
        {
            QMessageBox::information(this,
                                     tr("打开图像失败"),
                                     tr("打开图像失败!"));
            delete img;
            return;
        }
        ui->label->setPixmap(QPixmap::fromImage(*img));


 

显示的效果如图所示:

 用qt的label控件显示mjpg-streamer中的视频画面_第2张图片

很明显只能显示图片的一小部分。

 

二、修改label的大小

Qlable设置大小的函数有resize()

所以在添加图片前加上这行代码可以先调整好label的大小。
    

ui->label->resize(img->width(),img->height());

 

显示结果:

    用qt的label控件显示mjpg-streamer中的视频画面_第3张图片

好像图片过大了,label的大小已经超过了窗口的大小,还是不能完全显示,所以还是要找其他合适的解决方法。

 

 

我想label的大小范围是固定的,所以应该按比例缩放图片的大小,经过查阅资料有如下的方法:

首先用

label->setGeometry(0,0,400,300);//前两个参数表示label左上角位置后面分别是宽和高

函数设置lable的位置和大小,接着根据图片的大小缩放到合适的大小显示

图片缩放的相关函数是

img->scaled(width,height,Qt::KeepAspectRatio);

该函数前两个参数表示的是缩放之后图片的宽高,而第三个参数的作用是选择模式是否保持长宽比,相关的参数可以在qt的帮助文档中查看。接下来看使用了缩放之后的效果:

 用qt的label控件显示mjpg-streamer中的视频画面_第4张图片

的确能够把画面全部显示出来了。下面是mainwindows的构建代码:

{
    ui->setupUi(this);
    QString StrWidth,StrHeigth;
    QString filename="F:\\Study\\junior\\Qt\\door\\1.jpg";
            QImage* img=new QImage,* scaledimg=new QImage;//分别保存原图和缩放之后的图片
            if(! ( img->load(filename) ) ) //加载图像
            {
                QMessageBox::information(this,
                                         tr("打开图像失败"),
                                         tr("打开图像失败!"));
                delete img;
                return;
            }
            int Owidth=img->width(),Oheight=img->height();
            int Fwidth,Fheight;       //缩放后的图片大小
            ui->label->setGeometry(0,0,400,300);
            int Mul;            //记录图片与label大小的比例,用于缩放图片
            if(Owidth/400>=Oheight/300)
                Mul=Owidth/400;
            else
                Mul=Oheight/300;
            Fwidth=Owidth/Mul;
            Fheight=Oheight/Mul;
            *scaledimg=img->scaled(Fwidth,Fheight,Qt::KeepAspectRatio);
            ui->label_text->setText(QString("width: ")+StrWidth.setNum(Fwidth)
                                    +QString("\nheight: ")+StrHeigth.setNum(Fheight));
            ui->label->setPixmap(QPixmap::fromImage(*scaledimg));
}

 

2016.9.8

目标:在Qt的实现通过按钮控制在窗口中查看mjpeg-streamer运行时本地显示的摄像头画面。

 

思路:原来在html中只要直接插入图片标签,对应的地址"/?action=stream" ,在打开mjpeg-streamer的时候,就能在网页中显示对应的画面,所以我想在qt的label中将该地址引用为图片是否就可以直接看到画面,接下来就直接在上次的基础上修改代码试试。

 

事实证明我想的太简单了,image.load()只能打开本地的图片,对于网上的图片只能先保存为本地的图片然后再在控件里显示,所以接下来要解决的是如何获取网络上的图片。
查阅了资料之后发现就下载而言,Qt5的QtNetwork模块为我们提供了相当便利的接口,下面我就直接给出源码,相关的函数用法都可以参考帮助文档:

 

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QNetworkAccessManager *manager;
    manager = new QNetworkAccessManager(this);
    connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(slot_replyFinished(QNetworkReply*)));
    QNetworkRequest request;
    request.setUrl(QUrl("http://www.bz55.com/uploads/allimg/150707/139-150FG51639-50.jpg"));
    manager->get(request);
}
MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::slot_replyFinished(QNetworkReply* reply)
{
 QPixmap pix;
 QByteArray data = reply->readAll();
 pix.loadFromData(data, "JPG");
 pix.save("/root/Qt/program/netpicture/tmp1.jpg", "JPG", 100);
 ui->textEdit->resize(500,500);
 ui->textEdit->append("");
}


 

要注意的是在mainwindow.h里要写上

void MainWindow::slot_replyFinished(QNetworkReply* reply)


这个槽函数的声明并且加上

#include 
#include 
#include 


这几个头文件,在.pro文件中加上

QT+= network

这一行,接下来就可以编译运行了。

 用qt的label控件显示mjpg-streamer中的视频画面_第5张图片

代码中链接对应的图片就显示在了textEdit控件中了,当然在

“/root/Qt/program/netpicture”目录下也成功的下载了这个图片(不然也无法显示)。

 用qt的label控件显示mjpg-streamer中的视频画面_第6张图片

好了既然能显示网络上的图片了那就简单的修改一下源码试试在label中显示mjpeg-streamer生成的“http://localhost:8080/?action=stream图片,如果能够显示的话只要加上循环控制应该就可以显示视频了。

 

 

2016.9.10

coding...

 

2016.9.11

思考:经过一天的修改折腾想要的功能基本实现了,其中和预想的不一样的是要读取mjpg-streamer打开后对应的图片链接是http://localhost:8080/?action=snapshot

前面那个链接对应的是一个流,这才是一个静态图片。

还有一个难点是在执行了manager->get(request);并不能立即调用槽函数,所以紧接着执行在label中显示图片的语句的话会出现图片打开失败的错误提示,我想应该是向链接发出访问请求是需要一小段时间的虽然很短但还是比两行命令之间的时间差要长很多,所以我在这两行命令之间添加了延时代码,要注意的是不能调用系统的sleep()函数,因为这样你的控件就会失去响应,当然label上的画面也就不会刷新了。

接下来就直接贴出代码,这里我也将获取到的画面自动缩放到640*480大小:

QString PU="http://192.168.253.3:8080/?action=snapshot";
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    SetWindow();
}
MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::PicConnect(QString PicUrl)
{       //connect to picture
    QNetworkAccessManager *manager;
    manager = new QNetworkAccessManager(this);
    connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(slot_replyFinished(QNetworkReply*)));
    QNetworkRequest request;
    request.setUrl(QUrl(PicUrl));
    manager->get(request);
}
 
void MainWindow::slot_replyFinished(QNetworkReply* reply)
{       //save the picture
 QPixmap pix;
 QByteArray data = reply->readAll();
 pix.loadFromData(data, "JPG");
 pix.save("/root/Qt/program/netpicture/tmp1.jpg", "JPG", 100);
}
void MainWindow::SetWindow()
{       //set the window with one label and pushButton
    this->resize(800,600);
    ui->PicLabel->setGeometry(10,10,640,480);
    ui->PicLabel->setText("PICTURE......");
    ui->PicButton->setGeometry(300,500,30,15);
    isPicOnLabel=false;
    ui->PicButton->setText("Show");
}
void MainWindow::on_PicButton_clicked()
{
    if(isPicOnLabel==false)
    {
        ShowPic();
    }
    else
    {
        StopPic();
    }
}
void MainWindow::ShowPic()
{
    isPicOnLabel=true;
    ui->PicButton->setText("stop");
    while(1)
    {
            if(isPicOnLabel==false)
                break;
            PicConnect(PU);
            QEventLoop eventloop;
            QTimer::singleShot(10, &eventloop, SLOT(quit()));
//等待10*0.001秒
            eventloop.exec();
            if(! ( img->load("/root/Qt/program/netpicture/tmp1.jpg") ) ) //加载图像
            {
                QMessageBox::information(this,
                                         tr("打开图像失败"),
                                         tr("打开图像失败!"));
                delete img;
                return;
            }
            *scaledimg=img->scaled(640,480,Qt::KeepAspectRatio);
            ui->PicLabel->setPixmap(QPixmap::fromImage(*scaledimg));
    }
}
void MainWindow::StopPic()
{
    isPicOnLabel=false;
    ui->PicButton->setText("show");
}


 

其中mainwindow.h.需要包含的头文件以及需要添加的成员变量:

#include 
#include 
#include 
#include 
#include
#include
 
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    bool isPicOnLabel;
    explicit MainWindow(QWidget *parent = 0);    
    QImage* img=new QImage,* scaledimg=new QImage;
    ~MainWindow();
public slots:
    void slot_replyFinished(QNetworkReply* reply);
private slots:
    void on_PicButton_clicked();
private:
    Ui::MainWindow *ui;
    void PicConnect(QString p);
    void SetWindow();
    void ShowPic();
    void StopPic();
};


最后可以看一下程序运行的效果:

这是在按下“show”按钮之前

 用qt的label控件显示mjpg-streamer中的视频画面_第7张图片

 

按下之后:

 用qt的label控件显示mjpg-streamer中的视频画面_第8张图片

这时候能够看到连续的画面,帧数可以通过

QTimer::singleShot(10, &eventloop, SLOT(quit()));


的第一个参数来控制,第一个参数的单位是毫秒。

 

为了添加拍照功能,于是加上了一个savebutton,槽函数代码如下:

void MainWindow::on_SaveButton_clicked()
{
    if(isPicOnLabel==false)
    {
        QMessageBox::information(this,
                                 tr("ERROR!"),
                                 tr("NO PICTURE !"));
    }
    else
    {
        QString str_time,path;
        QDateTime time = QDateTime::currentDateTime();
        str_time = time.toString("yyyy-MM-dd_hh-mm-ss");
        path="../netpicture/photo/"+str_time+".jpg";
        QPixmap::fromImage(*img).save(path, "JPG", 100);
        QMessageBox::information(this,
                                 tr("save"),
                                 tr("PICTURE has been saved to folder 'photo!'"));
 
    }
}


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

后来再看了这个程序发现太多的问题了,析构函数没有写而且在循环显示图片的时候不断的new对象都没有delete,所以把原来的代码改了,没有用循环而是用的定时器来实现不断的刷新图片。下面我就直接把cpp文件全部贴上来。(都怪当初c++基础没学好啊!),不过下面有几个函数是录音和发送按钮的,还没有写好可以不看的。

#include "mainwindow.h"
#include
#include
#include
#include
#include 
#include
#include
#include
#include

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    setWindowIcon(QIcon(":/new/icon/srcs/title.png")); //设置窗口图标

    img = new QImage;
    scaledimg = new QImage;
    setWindowTitle("智能门神系统");


    isLocal=true;
    showTime=new QTimer;
    showTime->setInterval(130);
    connect(showTime, SIGNAL(timeout()), this, SLOT(flushPic()));
    manager = new QNetworkAccessManager(this);
    connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(slot_replyFinished(QNetworkReply*)));

    Address = "127.0.0.1";
    Port = "8080";
    PU="http://127.0.0.1:8080/?action=snapshot";    //默认地址为127.0.0.1 端口为8080
//    PU="http://127.0.0.1:8080/?action=stream";    //默认地址为127.0.0.1 端口为8080
    QWidget *mainwidgit = new QWidget();
    this->setCentralWidget(mainwidgit);
    //作为主界面,用来放置layout_main,可以解决
    //QLayout: Attempting to add QLayout "" to MainWindow "", which already has a layout
    //的问题

    //左侧按钮和加载图标的变量

    url_label = new QLabel("地址:");
    port_label = new QLabel("端口:");
    url_lineedit =new QLineEdit("127.0.0.1");
    url_lineedit->setMinimumWidth(100);
    url_lineedit->setMaximumWidth(100);
    port_lineedit = new QLineEdit("8080");
    port_lineedit->setMinimumWidth(100);
    port_lineedit->setMaximumWidth(100);

    button_islocal = new QPushButton;
    button_islocal->setText("LOCAL");
    button_islocal->setMinimumSize(70,25);
    button_islocal->setMaximumSize(70,25);

    QIcon button_ico(":/new/icon/srcs/movie.png");
    button_movie = new QPushButton;
    button_movie->setStyleSheet("QPushButton:pressed{border-image:url(:/new/icon/srcs/movieclick.png)}");
    button_movie->setMinimumSize(55,55);    //设置button固定大小就不会在layout里自动变化了
    button_movie->setMaximumSize(55,55);
    button_movie->setIcon(button_ico);
    button_movie->setIconSize(QSize(50,50));
    button_movie->setFlat(true);

    button_shot = new QPushButton();
    button_shot->setStyleSheet("QPushButton:pressed{border-image:url(:/new/icon/srcs/shotclick.png)}");
    button_ico.addFile(":/new/icon/srcs/shot.png");
    button_shot->setMinimumSize(55,55);
    button_shot->setMaximumSize(55,55);
    button_shot->setIcon(button_ico);
    button_shot->setIconSize(QSize(50,50));
    button_shot->setFlat(true);

    button_pictures = new QPushButton();
    button_ico.addFile(":/new/icon/srcs/pictures.png");
    button_pictures->setStyleSheet("QPushButton:pressed{border-image:url(:/new/icon/srcs/picturesclick.png)}");
    button_pictures->setMinimumSize(55,55);
    button_pictures->setMaximumSize(55,55);
    button_pictures->setIcon(button_ico);
    button_pictures->setIconSize(QSize(50,50));
    button_pictures->setFlat(true);

    button_record = new QPushButton();
    button_record->setStyleSheet("QPushButton:pressed{border-image:url(:/new/icon/srcs/recordclick.png)}");
    button_ico.addFile(":/new/icon/srcs/record.png");
    button_record->setMinimumSize(55,55);
    button_record->setMaximumSize(55,55);
    button_record->setIcon(button_ico);
    button_record->setIconSize(QSize(50,50));
    button_record->setFlat(true);

    button_play = new QPushButton();
    button_play->setStyleSheet("QPushButton:pressed{border-image:url(:/new/icon/srcs/playclick.png)}");
    button_ico.addFile(":/new/icon/srcs/play.png");
    button_play->setMinimumSize(55,55);
    button_play->setMaximumSize(55,55);
    button_play->setIcon(button_ico);
    button_play->setIconSize(QSize(50,50));
    button_play->setFlat(true);

    button_movieIsClicked = false;      //初始化按钮的状态
    button_recordIsClicked = false;
    layout_button = new QVBoxLayout();

    //关联按钮的信号和槽函数
    //connect()

    //左侧的logo
    logo_label = new QLabel();        //添加图片
    QImage *logo_img = new QImage(":/new/label/srcs/logo.png");
    QImage *scaled_logo_img = new QImage();
    *scaled_logo_img=logo_img->scaled(150,120,Qt::KeepAspectRatio);
    logo_label->setPixmap(QPixmap::fromImage(*scaled_logo_img));

    //把按钮控件放到左边的垂直布局中
    layout_button->addWidget(button_islocal);
    layout_button->addWidget(url_label);
    layout_button->addWidget(url_lineedit);
    layout_button->addWidget(port_label);
    layout_button->addWidget(port_lineedit);
    layout_button->addWidget(button_movie);
    layout_button->addWidget(button_shot);
    layout_button->addWidget(button_pictures);
    layout_button->addWidget(button_record);
    layout_button->addWidget(button_play);
    //把logolabel放进布局
    layout_logo = new QVBoxLayout();
    layout_logo->addWidget(logo_label);

    //右测
    movie_label = new QLabel();
    movie_label->setFrameStyle(QFrame::Panel|QFrame::Sunken);
    movie_label->resize(640,480);
    img = new QImage(":/new/label/srcs/nosignal.png");
    scaledimg = new QImage;
    *scaledimg=img->scaled(movie_label->width()/4,movie_label->height()/4,Qt::KeepAspectRatio);
    movie_label->setAlignment(Qt::AlignCenter);
    movie_label->setPixmap(QPixmap::fromImage(*scaledimg));

    layout_label = new QGridLayout();
    //将label添加到右侧布局中
    layout_label->addWidget(movie_label);

    //mainlayout
    QGridLayout *layout_main = new QGridLayout(); //让主窗口采用这个布局
    layout_main->setMargin(15);
    layout_main->setSpacing(10);
    layout_main->addLayout(layout_logo,0,0,1,1);
    layout_main->addLayout(layout_button,1,0,2,1);
    layout_main->addLayout(layout_label,0,1,3,5);

    //为编辑框添加失去焦点事件
//    connect(url_lineedit,&QLineEdit::returnPressed,this,&MainWindow::ChangeAddress);
//    connect(port_lineedit,&QLineEdit::returnPressed,this,&MainWindow::ChangePort);

    //为按钮添加事件
    connect(button_movie,&QPushButton::clicked, this,&MainWindow::Click_Button_movie);
    connect(button_shot, &QPushButton::clicked, this, &MainWindow::Click_Button_shot);
    connect(button_pictures,&QPushButton::clicked, this,&MainWindow::Click_Button_pictures);
    connect(button_islocal,&QPushButton::clicked,this,&MainWindow::on_button_islocal);
/*    connect(button_record,&QPushButton::clicked, this, &MainWindow::Click_Button_record);
    connect(button_play,&QPushButton::clicked, this, &MainWindow::Click_Button_play);
    */

    if(!QDir("temp").exists())
    {
        QDir dir;
        dir.mkpath("temp");
    }

    //将mainlayout加到mainwidget上去
    mainwidgit->setLayout(layout_main);
    this->resize(800,600);

    /********** Send and receive message though UCP protocol **************/
    UdpSender = new QUdpSocket(this);
    UdpReader = new QUdpSocket(this);
    // 将UdpReader绑定到localhost的6666端口,接收发到这个端口的信息
    bool result=UdpReader->bind(6666);
    if(!result)
    {
     QMessageBox::information(this,tr("error"),tr("udp socket create error!"));
     return ;
    }
    record = new QProcess;
    play = new QProcess;
    sendfile=new QFile("/root/server/record.mp3");
    recivefile=new QFile("/root/server/play.mp3");
    recivefile->resize(0);

    connect(UdpReader, SIGNAL(readyRead()), this, SLOT(readMessage()));
    connect(button_play,SIGNAL(clicked()),this,SLOT(on_button_play_clicked()));
    connect(button_record,SIGNAL(clicked()),this,SLOT(on_button_record_clicked()));
    connect(UdpReader,SIGNAL(readyRead()),this,SLOT(getAmessege()));

    totalBytes=0;
    loadSize=4*1024;//每次发送4kb
    bytesToWrite=0;

}



MainWindow::~MainWindow()
{
    QFile::remove("temp/temp1.jpg");
    delete img;
    delete scaledimg;
    delete url_label;
    delete port_label;
    delete url_lineedit;
    delete port_lineedit;
    delete button_movie;
    delete button_pictures;
    delete button_play;
    delete button_record;
    delete button_shot;
    delete layout_button;
    delete layout_logo;
    delete logo_label;
    delete movie_label;
    delete layout_label;
    delete button_islocal;
}
void MainWindow::paintEvent(QPaintEvent *event)
{
   QPainter painter(this);
   painter.drawPixmap(0,0,width(),height(),QPixmap(":/new/wall/srcs/wall.jpg"));
}



void MainWindow::slot_replyFinished(QNetworkReply* reply)
{       //save the picture
 QPixmap pix;
 QByteArray data = reply->readAll();
 pix.loadFromData(data, "JPG");
 pix.save("temp/temp1.jpg", "JPG", 50);

 if(! ( img->load("temp/temp1.jpg") ) ) //加载图像
 {
     showTime->stop();
     QMessageBox::information(this,
                              tr("警告"),
                              tr("图像载入失败!"));
     button_movieIsClicked=false;
     QIcon button_ico1(":/new/icon/srcs/movie.png");
     button_movie->setIcon(button_ico1);
     return;
 }
 *scaledimg=img->scaled(this->width()*4/5,this->height()*4/5,Qt::KeepAspectRatio);
 movie_label->setPixmap(QPixmap::fromImage(*scaledimg));

}
void MainWindow::Click_Button_movie()
{
    Address=url_lineedit->text();
    Port=port_lineedit->text();
    if(isLocal)     //判断是否为本地视频
        PU="http://"+Address+":"+Port+"/?action=snapshot/";
    else
        PU="http://"+Address+"/proxy/?action=snapshot";
    if(button_movieIsClicked==false)
    {
        QIcon button_cio(":/new/icon/srcs/stop.png");
        button_movie->setIcon(button_cio);

        button_movieIsClicked=true;
        showTime->start();
    }
    else
    {
        QIcon button_ico1(":/new/icon/srcs/movie.png");
        button_movie->setIcon(button_ico1);
        button_movieIsClicked=false;
        showTime->stop();
    }
}
void MainWindow::on_button_islocal()
{
    if(isLocal)
        button_islocal->setText("WAN");
    else
        button_islocal->setText("LOCAL");
    isLocal=!isLocal;
}
void MainWindow::flushPic()
{
    request.setUrl(QUrl(PU));
    manager->get(request);
/*    if(! ( img->load("temp/temp1.jpg") ) ) //加载图像
    {
        QMessageBox::information(this,
                                 tr("警告"),
                                 tr("图像载入失败!"));
        button_movieIsClicked=false;
        QIcon button_ico1(":/new/icon/srcs/movie.png");
        button_movie->setIcon(button_ico1);
        showTime->stop();
    }
    *scaledimg=img->scaled(this->width()*4/5,this->height()*4/5,Qt::KeepAspectRatio);
    movie_label->setPixmap(QPixmap::fromImage(*scaledimg));
    */
}


void MainWindow::Click_Button_shot()
{
    if(!QDir("photo").exists())
    {
        QDir dir;
        dir.mkpath("photo");
    }
    QString str_time,path;
    QDateTime time = QDateTime::currentDateTime();
    str_time = time.toString("yyyy-MM-dd_hh-mm-ss");
    path="./photo/"+str_time+".jpg";
    QPixmap::fromImage(*img).save(path, "JPG", 100);
    QMessageBox::information(this,
                             tr("save"),
                             tr("PICTURE has been saved to folder 'photo!'"));
}
void MainWindow::Click_Button_pictures()
{
    QIcon button_ico1(":/new/icon/srcs/movie.png");
    button_movie->setIcon(button_ico1);
    button_movieIsClicked=false;

    QFileDialog pho;
    pho.setDirectory(QString("photo"));
    pho.setWindowTitle("截图");
    if(pho.exec())
    {
        QStringList filePath=pho.selectedFiles();
        img->load(filePath[0]);
        *scaledimg=img->scaled(movie_label->width(),movie_label->height(),Qt::KeepAspectRatio);
        movie_label->setPixmap(QPixmap::fromImage(*scaledimg));


    }
}



void MainWindow::sendMessage()
{
      /*totalBytes=sendfile->size();
      int sendNum=totalBytes/loadSize;
      for(int i=0;iread(loadSize);
        UdpSender->writeDatagram(line,QHostAddress("127.0.0.0"),7777);
        line.resize(0);
      }
      bytesToWrite=totalBytes-sendNum*loadSize;
      QByteArray line=sendfile->read(bytesToWrite);
      UdpSender->writeDatagram(line,QHostAddress("127.0.0.0"),7777);
      line.resize(0);
      qDebug()<<"send over!";
      sendfile->close();*/

    QByteArray line = sendfile->read(sendfile->size());
    UdpSender->writeDatagram(line,QHostAddress("127.0.0.0"),7777);
    line.resize(0);
    qDebug()<<"send over!";
    sendfile->close();
}
void MainWindow::readMessage()
{
    if(!recivefile->open(QIODevice::WriteOnly))
    {
       qDebug()<<"open play.mp3 error !";
       return;
    }
    while (UdpReader->hasPendingDatagrams())
    {
        QByteArray datagram;
        datagram.resize(UdpReader->pendingDatagramSize());
        QHostAddress sender;
        quint16 senderPort;
        UdpReader->readDatagram(datagram.data(), datagram.size(),&sender,&senderPort);
       // qDebug() <write(datagram.data(),datagram.size());
    }
    recivefile->close();
    qDebug() <<"recive success!";

}

void MainWindow::on_button_play_clicked()
{
      bool play_copyIsexit=QFile::exists("/root/server/play_copy.mp3");
      int playmp3Size=recivefile->size();
      if(play_copyIsexit&&playmp3Size)
      {
           QFile::remove("/root/server/play_copy.mp3");
           if(!QFile::copy("/root/server/play.mp3","/root/server/play_copy.mp3"))
               qDebug() <<"copy error!";
      }
      if(!play_copyIsexit&&!playmp3Size)
          QMessageBox::information(this,
                                   tr("messege"),
                                   tr("历史消息为空!"));
      if(!play_copyIsexit&&playmp3Size)
      {
          if(!QFile::copy("/root/server/play.mp3","/root/server/play_copy.mp3"))
              qDebug() <<"copy error!";
      }
      play->start("play /root/server/play_copy.mp3 bass +35");
      recivefile->resize(0);
      recivefile->close();
      qDebug() <<"playing ......";
}


void MainWindow::on_button_record_clicked()
{
    if(button_recordIsClicked==false)
    {
      button_recordIsClicked=true;
      QIcon button_ico(":/new/icon/srcs/send.png");
      button_record->setIcon(button_ico);
      QFile::remove("/root/server/record.mp3");
      record->start("avconv -f alsa -i hw:0 /root/server/record.mp3");
    }
    else
    {
       record->close();
       button_recordIsClicked=false;
       QIcon button_ico1(":/new/icon/srcs/record.png");
       button_record->setIcon(button_ico1);
       if(!sendfile->open(QIODevice::ReadOnly))
       {
           qDebug()<< "open record.mp3 error!";
           return;
       }
       sendMessage();
    }
}

void MainWindow::getAmessege()
{
    QMessageBox::information(this,
                             tr("messege"),
                             tr("A new messege!"));
}




这里是mainwindow.h文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include
#include
#include
#include
#include
#include 
#include 
#include 
#include
#include
#include 
#include 
#include
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
    QImage* img,* scaledimg;
    void ShowPic();
    QTimer *showTime;
    QNetworkAccessManager *manager;
    QNetworkRequest request;

public slots:
    void slot_replyFinished(QNetworkReply* reply);
    void Click_Button_movie();
    void Click_Button_shot();
    void getAmessege();
    void Click_Button_pictures();
    void sendMessage(); // 发送消息
    void readMessage(); // 接受信息
    void on_button_play_clicked();
    void on_button_record_clicked();
    void flushPic();
    void on_button_islocal();
//    void ChangeAddress();
//    void ChangePort();


private:        //主窗口中需要用到的控件和布局的指针
    //左边的按钮和显示logo的label
    QLabel *url_label;
    QLabel *port_label;
    QLineEdit *url_lineedit;
    QLineEdit *port_lineedit;
    QPushButton *button_movie;
    QPushButton *button_shot;
    QPushButton *button_pictures;
    QPushButton *button_record;
    QPushButton *button_play;
    QPushButton *button_islocal;
    QVBoxLayout *layout_button;
    QVBoxLayout *layout_logo;
    QLabel *logo_label;

    //两个UDPSocket,一个接收一个发送
    QUdpSocket *UdpSender;
    QUdpSocket *UdpReader;
    //两个文件,一个保存将要发送的MP3文件,一个保存接收到的MP3文件
    QFile *sendfile;
    QFile *recivefile;
    //两个Process分别调用外部录音和播音软件
    QProcess *record;
    QProcess *play;

    qint64 totalBytes;  //数据总大小
    qint64 bytesWritten;  //已经发送数据大小
    qint64 bytesToWrite;   //剩余数据大小
    qint64 loadSize;   //每次发送数据的大小
    //mjpeg-stream画面的地址
    QString Address,Port,PU;


    //记录按钮状态
    bool button_movieIsClicked; //控制显示“moive”或者“stop”
    bool button_recordIsClicked;//控制显示“record”或者“send”
    bool isLocal;//是否为局域网视频

    //右边显示视频画面的label
    QLabel *movie_label;
    QGridLayout *layout_label;
protected:
    void paintEvent(QPaintEvent *event);
    void SetWindow();



};

#endif // MAINWINDOW_H


 

你可能感兴趣的:(编程,Qt,Qt,编程,图形)