开篇先放一个很好的Qt5的学习链接:链接
这篇文章默认是你已经搭建好了windows和树莓派的Qt5的环境
Qt两个项目继承的基类都是Qwidget
本文用到的Qt知识有:
1、信号槽机制
2、Qt的网络编程
3、Qt的pushbutton,lable,textedit部件
我的学习一门语言或者一种语法的技巧就是学最精华的部分,学自己要用到的部分。现在学习的编程语言很多,也不可能去一个个细致的学习。掌握了最精华的部分就是关键!
#ifndef CLIENT_H
#define CLIENT_H
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace cv;
namespace Ui {
class Client;
}
class Client : public QWidget
{
Q_OBJECT
public:
explicit Client(QWidget *parent = 0);
~Client();
qint64 blockSize;
QTcpSocket* tcpSocket;
VideoCapture cap;
QTimer* timer;
private slots:
void displayError(QAbstractSocket::SocketError);
void requestNewFortune();
void enableGetFortuneButton();
void SendData();
private:
Ui::Client *ui;
};
#endif // CLIENT_H
Client.cpp
#include "client.h"
#include "ui_client.h"
Client::Client(QWidget *parent) :
QWidget(parent),
ui(new Ui::Client)
{
ui->setupUi(this);
ui->Fortune_ptn->setGeometry(100,330,80,80);
ui->quit_ptn->setGeometry(360,330,80,80);
tcpSocket=new QTcpSocket(this);
timer=new QTimer(this);
cap.open(0);
if(!cap.isOpened()){
QMessageBox::information(this,tr("提示"),tr("摄像头没有打开"));
}
connect(ui->Fortune_ptn,SIGNAL(clicked(bool)),this,SLOT(requestNewFortune()));
connect(ui->quit_ptn,SIGNAL(clicked(bool)),this,SLOT(enableGetFortuneButton()));
connect(timer,SIGNAL(timeout()),this,SLOT(SendData()));
connect(tcpSocket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(displayError(QAbstractSocket::SocketError)));
}
Client::~Client()
{
delete ui;
}
void Client::displayError(QAbstractSocket::SocketError)
{
qDebug()<<"传输失败!";
}
void Client::requestNewFortune()
{
timer->start(30);
ui->Fortune_ptn->setEnabled(true);
}
void Client::enableGetFortuneButton()
{
ui->Fortune_ptn->setEnabled(true);
tcpSocket->disconnectFromHost();
timer->stop();
}
void Client::SendData()
{
blockSize=0;
tcpSocket->abort();
tcpSocket->connectToHost(QHostAddress::LocalHost,8888);
Mat frame;
cap>>frame;
cvtColor(frame,frame,CV_BGR2RGB);
QByteArray byte;
QBuffer buf(&byte);
QImage image((unsigned const char*)frame.data,frame.cols,frame.rows,QImage::Format_RGB888);
image.save(&buf,"JPEG");
QByteArray ss=qCompress(byte,1);
QByteArray vv=ss.toBase64();
QByteArray ba;
QDataStream out(&ba,QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_5_6);
out<<(quint64)0;
out<seek(0);
out<<(quint64)(ba.size()-sizeof(quint64));
tcpSocket->write(ba);
ui->image_label->setGeometry(0,0,551,321);
ui->image_label->setPixmap(QPixmap::fromImage(image));
//ui->image_label->resize(image.size());
update();
}
Server.h
#ifndef SERVER_H
#define SERVER_H
#include
#include
#include
#include
#include
//#include
#include
#include
namespace Ui {
class Server;
}
class Server : public QWidget
{
Q_OBJECT
public:
explicit Server(QWidget *parent = 0);
~Server();
QTcpServer *tcpServer;
QTcpSocket *tcpServerConnection;
QStringList *fortunes;
QImage *img;
quint64 basize;
public slots:
void sendFortune();
QByteArray GetPicData(QString fromPic);
void DisplayError(QAbstractSocket::SocketError socketError);
void ReadMyData();
void ShowImage(QByteArray ba);
private:
Ui::Server *ui;
};
#endif // SERVER_H
server.cpp
#include "server.h"
#include "ui_server.h"
Server::Server(QWidget *parent) :
QWidget(parent),
ui(new Ui::Server)
{
ui->setupUi(this);
tcpServer = new QTcpServer(this);
if(!tcpServer->listen(QHostAddress::Any,8888))
{
QMessageBox::critical(this,tr("Fortune Server"),tr("Unable to start the server:%l.").arg(tcpServer->errorString()));
close();
return;
}
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(sendFortune()));
}
Server::~Server()
{
delete ui;
}
void Server::sendFortune()
{
basize=0;
tcpServerConnection = tcpServer->nextPendingConnection();
connect(tcpServerConnection,SIGNAL(readyRead()),this,SLOT(ReadMyData()));
connect(tcpServerConnection,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(DisplayError(QAbstractSocket::SocketError)));
}
QByteArray Server::GetPicData(QString fromPic)
{
QImage img(fromPic);
QByteArray block;
QBuffer buf(&block);
img.save(&buf,"JPEG");//按照JPG解码保存数据
QByteArray cc = qCompress(block,1);
QByteArray hh;
hh=cc.toBase64();//base64数据
return hh;
}
void Server::DisplayError(QAbstractSocket::SocketError socketError)
{
tcpServerConnection->close();
}
void Server::ReadMyData()
{
QByteArray message;//存放从服务器接收到的字符串
QDataStream in(tcpServerConnection);
in.setVersion(QDataStream::Qt_5_6);
if (basize==0)
{
//判断接收的数据是否有两字节(文件大小信息)
//如果有则保存到basize变量中,没有则返回,继续接收数据
if (tcpServerConnection->bytesAvailable()<(int)sizeof(quint64))
{
return;
}
in>>basize;
}
//如果没有得到全部数据,则返回继续接收数据
if (tcpServerConnection->bytesAvailable()>message;//将接收到的数据存放到变量中
ShowImage(message);
}
void Server::ShowImage(QByteArray ba)
{
QString ss=QString::fromLatin1(ba.data(),ba.size());
QByteArray rc;
rc=QByteArray::fromBase64(ss.toLatin1());
QByteArray rdc=qUncompress(rc);
QImage img;
img.loadFromData(rdc);
ui->image_label->setGeometry(0,0,631,401);
ui->image_label->setPixmap(QPixmap::fromImage(img));
//ui->image_label->resize(img.size());
update();
}
实验的结果:
可见是成功的!完成了监控。
期间遇到一些问题,在这里总结一下
这里是没有添加pushbutton部件,这里显示Client类没有这两个成员
这里是无效的类型,这里由于我的疏忽没有引入Qtimer头文件
这里没有引入Qbuffer头文件
以及一些奇怪的错误,原因在于没有引入network模块
参考博客:https://blog.csdn.net/u013812682/article/details/52185540