一、前言上一篇文章已经打通了
数据源之一的
串口采集,这次要说的是网络采集,网络通信目前用的最多的是三种,TCP/UDP/HTTP,其中tcp通信又包括了客户端服务端两种,tcp通信才用了多次握手机制不丢包,但是耗费资源多而且需要建立连接。udp通信在大数据量或者网络不稳定的情况下,可能丢包,而且顺序无法保证,但是一个包的数据肯定是正确的,由于占用资源极少而且不需要建立连接,在很多场景中应用也蛮多,我个人用udp以来,也没发现过丢包的情况,可能数据量不够大或者是在局域网内的原因吧,反正用起来还是蛮爽的。http通信目前非常流行,尤其是和服务器之间做数据交互,基本上post请求然后返回一串json数据,解析对应的json数据即可。本次采用的TCP通信作为示例,
其他两种可以自行拓展,也很简单的。
体验地址:[
https://pan.baidu.com/s/1A5Gd77kExm8Co5ckT51vvQ](https://pan.baidu.com/s/1A5Gd77kExm8Co5ckT51vvQ) 提取码:877p 文件:可执行
文件.zip
二、实现的功能1. 自动加载
插件文件中的所有控件生成列表,默认自带的控件超过120个。
2. 拖曳到画布自动生成对应的控件,所见即所得。
3. 右侧中文属性栏,改变对应的属性立即应用到对应选中控件,直观简洁,非常适合小白使用。
4. 独创属性栏文字翻译映射机制,效率极高,可以非常方便拓展其他语言的属性栏。
5. 所有控件的属性自动提取并
显示在右侧属性栏,包括枚举值下拉框等。
6. 支持手动选择插件文件,外部导入插件文件。
7. 可以将当前画布的所有控件配置信息导出到xml文件。
8. 可以手动选择xml文件打开控件布局,自动根据xml文件加载控件。
9. 可拉动滑动条、勾选模拟数据复选框、文本框输入,三种方式来生成数据应用所有控件。
10. 控件支持八个方位拉动调整大小,自适应任意分辨率,可键盘上下左右微调位置。
11. 打通了串口采集、网络采集、
数据库采集三种方式设置数据。
12. 代码极其精简,注释非常详细,可以作为组态的雏形,自行拓展更多的功能。
13. 纯Qt编写,支持任意Qt版本+任意
编译器+任意系统。
三、效果图四、核心代码- void frmData::initServer()
- {
- //实例化串口类,绑定信号槽
- com = new QextSerialPort(QextSerialPort::EventDriven, this);
- connect(com, SIGNAL(readyRead()), this, SLOT(readDataCom()));
- //实例化网络通信客户端类,绑定信号槽
- tcpClient = new QTcpSocket(this);
- connect(tcpClient, SIGNAL(readyRead()), this, SLOT(readDataClient()));
- //实例化网络通信服务端类,绑定信号槽
- tcpSocket = NULL;
- tcpServer = new QTcpServer(this);
- connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newConnection()));
- //开启定时器读取数据库采集数据
- timer = new QTimer(this);
- connect(timer, SIGNAL(timeout()), this, SLOT(readDataDb()));
- timer->setInterval(1000);
- }
- void frmData::on_btnOpenTcpClient_clicked()
- {
- if (ui->btnOpenTcpClient->text() == "连接") {
- tcpClient->connectToHost(App::TcpServerIP, App::TcpServerPort);
- bool ok = tcpClient->waitForConnected(1000);
- if (ok) {
- setEnable(ui->btnOpenTcpClient, false);
- ui->btnOpenTcpClient->setText("断开");
- }
- } else {
- tcpClient->disconnectFromHost();
- setEnable(ui->btnOpenTcpClient, true);
- ui->btnOpenTcpClient->setText("连接");
- }
- }
- void frmData::on_btnOpenTcpServer_clicked()
- {
- if (ui->btnOpenTcpServer->text() == "监听") {
- #if (QT_VERSION > QT_VERSION_CHECK(5,0,0))
- bool ok = tcpServer->listen(QHostAddress::AnyIPv4, App::TcpListenPort);
- #else
- bool ok = tcpServer->listen(QHostAddress::Any, App::TcpListenPort);
- #endif
- if (ok) {
- setEnable(ui->btnOpenTcpServer, false);
- ui->btnOpenTcpServer->setText("停止");
- }
- } else {
- if (tcpSocket != NULL) {
- tcpSocket->disconnectFromHost();
- }
- tcpSocket = NULL;
- tcpServer->close();
- setEnable(ui->btnOpenTcpServer, true);
- ui->btnOpenTcpServer->setText("监听");
- }
- }
- void frmData::readDataClient()
- {
- QByteArray data = tcpClient->readAll();
- if (data.length() <= 0) {
- return;
- }
- //默认取第一个字节解析,可以自行更改
- quint8 value = data.at(0);
- ui->txtValue->setText(QString::number(value));
- append(3, data.toHex());
- }
- void frmData::readDataServer()
- {
- QByteArray data = tcpSocket->readAll();
- if (data.length() <= 0) {
- return;
- }
- //默认取第一个字节解析,可以自行更改
- quint8 value = data.at(0);
- ui->txtValue->setText(QString::number(value));
- append(3, data.toHex());
- }
- void frmData::newConnection()
- {
- while(tcpServer->hasPendingConnections()) {
- if (tcpSocket != NULL) {
- tcpSocket->disconnectFromHost();
- }
- tcpSocket = tcpServer->nextPendingConnection();
- connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readDataServer()));
- }
- }