QT局域网监控系统
Posted 狗蛋儿l
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QT局域网监控系统相关的知识,希望对你有一定的参考价值。
客户端ui:
头文件:
#ifndef MYWIN_H
#define MYWIN_H
#include <QWidget>
#include <QTcpSocket>
namespace Ui {
class MyWin;
}
class MyWin : public QWidget
{
Q_OBJECT
public:
explicit MyWin(QWidget *parent = 0);
~MyWin();
void paintEvent(QPaintEvent *e);
private slots:
void on_bnt_connect_clicked();
void disconnect_slot();
void read_data();
private:
Ui::MyWin *ui;
QTcpSocket *socket;
char *data;
int len; //图像大小
int len_rcv; //接收大小
};
#endif // MYWIN_H
主文件:
#include "mywin.h"
#include <QApplication>
#include <QWidget>
#define W 360
#define H 380
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget wid;
MyWin w(&wid), w2(&wid), w3(&wid), w4(&wid);
w.setGeometry(0, 0, W, H);
w2.setGeometry(W, 0, W, H);
w3.setGeometry(0, H, W, H);
w4.setGeometry(W, H, W, H);
wid.show();
return a.exec();
}
窗口文件:
#include "mywin.h"
#include "ui_mywin.h"
#include <QMessageBox>
#include <QDebug>
#include <QPainter>
#define LEN 3*1024*1024
#define P_LEN 1380
MyWin::MyWin(QWidget *parent) :
QWidget(parent),
ui(new Ui::MyWin)
{
ui->setupUi(this);
socket = new QTcpSocket(this);
connect(socket, SIGNAL(disconnected()), this, SLOT(disconnect_slot()));
connect(socket, SIGNAL(readyRead()), this, SLOT(read_data()));
data = new char[LEN];
}
MyWin::~MyWin()
{
delete ui;
delete [] data;
delete socket;
}
void MyWin::paintEvent(QPaintEvent *e)
{
QPixmap map;
if ((len_rcv >= len) && (len > 0))
{
map.loadFromData((uchar *)data, len);
QPainter p(this);
p.drawPixmap(10, 80, 320, 240, map);
socket->write("new_request");
len_rcv = 0;
}
}
void MyWin::read_data()
{
int ret;
ret = socket->read(data+len_rcv, P_LEN);
if (0 == strncmp("newImage", data+len_rcv, 8))
{
len = atoi(data+len_rcv+9);
// qDebug() << len;
}
else
{
len_rcv += ret;
if (len_rcv >= len)
{
update();
return;
}
}
socket->write("ack");
}
void MyWin::disconnect_slot()
{
ui->bnt_connect->setEnabled(true);
}
void MyWin::on_bnt_connect_clicked()
{
QString ip = ui->lnd_ip->text();
socket->connectToHost(ip, 12345);
if (!socket->waitForConnected(1000))
{
QMessageBox::critical(this, "error", "server connection failed");
return;
}
len_rcv = 0;
socket->write("new_request");
ui->bnt_connect->setEnabled(false);
}
服务端ui:
头文件:
#ifndef MYWIN_H
#define MYWIN_H
#include <QWidget>
#include <QCamera>
#include <QCameraViewfinder>
#include <QTcpServer>
#include <QTcpSocket>
#include <QList>
#include <QTimer>
namespace Ui {
class MyWin;
}
class MyWin : public QWidget
{
Q_OBJECT
public:
explicit MyWin(QWidget *parent = 0);
~MyWin();
private slots:
void new_client();
void distconnect_client();
void read_data();
void timer_slot();
private:
Ui::MyWin *ui;
QCamera *cam;
QCameraViewfinder *view;
QTcpServer *server;
QList<QTcpSocket *> clients;
QTimer *timer;
};
#endif // MYWIN_H
主文件:
#include "mywin.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyWin w;
w.show();
return a.exec();
}
窗口文件:
#include "mywin.h"
#include "ui_mywin.h"
#include <QMessageBox>
#include <QScreen>
#include <QBuffer>
#define W 640
#define H 480
#define LEN (W*H*2)
#define P_LEN 1380
class Data {
public:
char data[LEN]; //图像数据
int len; //图像大小
int len_sent; //已发出的数据长度
int stats; //工作状态, 0表示空闲(图像数据可以更新), 1表示图像数据传输中(还不可以更新图像数据), 2表示需要发出图像数据的第一部分
Data() {
len_sent = 0;
stats = 0;
}
};
MyWin::MyWin(QWidget *parent) :
QWidget(parent),
ui(new Ui::MyWin)
{
ui->setupUi(this);
server = new QTcpServer(this);
if (!server->listen(QHostAddress::Any, 12345))
{
QMessageBox::critical(this, "error", "listen port failed");
exit(0);
}
connect(server, SIGNAL(newConnection()), this, SLOT(new_client()));
cam = new QCamera;
view = new QCameraViewfinder(this);
view->setGeometry(0, 0, W, H);
view->show();
cam->setViewfinder(view);
cam->start();
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(timer_slot()));
timer->start(100);
resize(640, 600);
}
MyWin::~MyWin()
{
delete ui;
cam->stop();
delete cam;
delete view;
delete server;
}
void MyWin::timer_slot()
{
QString s("newImage:%1");
QScreen *screen = QApplication::primaryScreen();
QPixmap map = screen->grabWindow(view->winId()); //只截view窗口对象上的图像,也就是摄像头的数据
//再编码成jpg图像
QByteArray ba;
QBuffer bf(&ba);
map.save(&bf, "jpg", 50);
//给每个QTcpSocket对象更新图像数据
for (int i = 0; i < clients.size(); i++)
{
Data *d = (Data*)clients.at(i)->userData(0);
if (d->stats != 1) // 1表示传输中
{
memcpy(d->data, ba.data(), ba.size());
d->len = ba.size();
if (d->stats == 2)
{
d->stats = 1; //改为传输中的状态
d->len_sent = 0;
clients.at(i)->write(s.arg(d->len).toUtf8());
}
}
}
}
void MyWin::read_data()
{
QTcpSocket *client = qobject_cast<QTcpSocket *>(sender());
QString str = client->readAll();
Data *d = (Data*)client->userData(0);
QString s("newImage:%1");
if (str == "new_request")
{
if ((d->len) && (d->stats==0)) //图像大小不为0,表示已更新图像数据了
{
d->stats = 1;
client->write(s.arg(d->len).toUtf8());
d->len_sent = 0;
}
else //图像数据还没有更新
d->stats = 2; //在定时器的槽函数里发出"newImage..."
}
if (str == "ack")
{
int len_send = P_LEN;
if (d->len_sent >= d->len) //如果图像已传输完毕
return;
if ((d->len_sent + P_LEN) > d->len)
len_send = d->len - d->len_sent;
d->len_sent += client->write(d->data+d->len_sent, len_send);
if (d->len_sent >= d->len)
{
d->stats = 0; //传输完毕后,把状态改为可更新
d->len = 0;
}
}
}
void MyWin::distconnect_client()
{
QTcpSocket *client = qobject_cast<QTcpSocket *>(sender());
Data *d = (Data*)client->userData(0);
clients.removeOne(client);
}
void MyWin::new_client()
{
QTcpSocket *client = server->nextPendingConnection();
connect(client, SIGNAL(disconnected()), this, SLOT(distconnect_client()));
connect(client, SIGNAL(readyRead()), this, SLOT(read_data()));
client->setUserData(0, (QObjectUserData *)new Data);
clients.append(client);
}
以上是关于QT局域网监控系统的主要内容,如果未能解决你的问题,请参考以下文章
26.Qt Quick QML-RotationAnimationPathAnimationSmoothedAnimationBehaviorPauseAnimationSequential(代码片段
Qt 5.8 QTcpServer 无法监听局域网 ip 地址问题