2024-11-04 21:11:39 +08:00
|
|
|
|
#include "coaldistributbarchartwidget.h"
|
2024-11-01 17:40:37 +08:00
|
|
|
|
|
|
|
|
|
#include <QDateTimeAxis>
|
|
|
|
|
#include <QList>
|
|
|
|
|
#include <QRandomGenerator>
|
|
|
|
|
#include <QScopedPointer>
|
2024-11-04 18:11:55 +08:00
|
|
|
|
#include <QTcpSocket>
|
2024-11-01 17:40:37 +08:00
|
|
|
|
#include <QVBoxLayout>
|
|
|
|
|
#include <QtCharts/QChart>
|
|
|
|
|
|
|
|
|
|
#include <QBarSeries>
|
|
|
|
|
#include <QBarSet>
|
|
|
|
|
#include <QChart>
|
|
|
|
|
#include <QChartView>
|
2024-11-04 18:11:55 +08:00
|
|
|
|
#include <QColor>
|
2024-11-01 17:40:37 +08:00
|
|
|
|
#include <QDateTimeAxis>
|
|
|
|
|
#include <QTimer>
|
|
|
|
|
#include <QVBoxLayout>
|
|
|
|
|
|
|
|
|
|
#include <memory>
|
|
|
|
|
|
2024-11-12 17:35:54 +08:00
|
|
|
|
CoalDistributBarChartWidget::CoalDistributBarChartWidget(QWidget* parent)
|
|
|
|
|
: QWidget(parent)
|
|
|
|
|
, m_tcpSocket(new QTcpSocket(this))
|
|
|
|
|
{
|
|
|
|
|
initializeChart();
|
2024-11-01 17:40:37 +08:00
|
|
|
|
|
2024-11-12 17:35:54 +08:00
|
|
|
|
m_systemSetting = new QSettings("system.ini", QSettings::IniFormat);
|
2024-11-04 18:11:55 +08:00
|
|
|
|
|
2024-11-12 17:35:54 +08:00
|
|
|
|
connectTCPSocket();
|
2024-11-04 18:11:55 +08:00
|
|
|
|
|
2024-11-12 17:35:54 +08:00
|
|
|
|
setupTimer();
|
2024-11-01 17:40:37 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-12 17:35:54 +08:00
|
|
|
|
CoalDistributBarChartWidget::~CoalDistributBarChartWidget()
|
|
|
|
|
{
|
|
|
|
|
if (m_tcpSocket->state() == QAbstractSocket::ConnectedState) {
|
|
|
|
|
m_tcpSocket->disconnectFromHost();
|
|
|
|
|
m_tcpSocket->waitForDisconnected();
|
|
|
|
|
}
|
|
|
|
|
delete m_tcpSocket;
|
2024-11-05 17:48:05 +08:00
|
|
|
|
}
|
2024-11-04 18:11:55 +08:00
|
|
|
|
|
2024-11-12 17:35:54 +08:00
|
|
|
|
void CoalDistributBarChartWidget::updateChart()
|
|
|
|
|
{
|
|
|
|
|
int radio = getCoalRatioByTCPSocket();
|
|
|
|
|
if (radio < 0 || radio > 90) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-11-01 17:40:37 +08:00
|
|
|
|
|
2024-11-12 17:35:54 +08:00
|
|
|
|
int setCount = m_set->count();
|
2024-11-01 17:40:37 +08:00
|
|
|
|
|
2024-11-12 17:35:54 +08:00
|
|
|
|
m_set->remove(setCount - 1);
|
|
|
|
|
m_set->insert(0, radio);
|
2024-11-01 17:40:37 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-12 17:35:54 +08:00
|
|
|
|
void CoalDistributBarChartWidget::initializeChart()
|
|
|
|
|
{
|
|
|
|
|
// 创建图标
|
|
|
|
|
m_chart = new QChart();
|
|
|
|
|
|
|
|
|
|
m_chart->setBackgroundBrush(Qt::transparent);
|
|
|
|
|
m_chart->setMargins(QMargins(0, 0, 0, 0));
|
|
|
|
|
m_chart->legend()->hide();
|
|
|
|
|
|
|
|
|
|
// 创建窗口并设置图表
|
|
|
|
|
m_chartView = new QChartView(m_chart);
|
|
|
|
|
m_chartView->setBackgroundBrush(Qt::transparent);
|
|
|
|
|
m_chartView->setStyleSheet("background: transparent;"); // 使用样式表确保透明
|
|
|
|
|
m_chartView->setRenderHint(QPainter::Antialiasing);
|
|
|
|
|
m_chartView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
|
|
|
|
|
|
|
|
// 创建柱状图
|
|
|
|
|
m_series = new QBarSeries();
|
|
|
|
|
m_chart->addSeries(m_series);
|
|
|
|
|
|
|
|
|
|
// 设置X轴为据煤溜摄像机距离
|
|
|
|
|
QValueAxis* axisX = new QValueAxis;
|
|
|
|
|
axisX->setRange(1, 300);
|
|
|
|
|
axisX->setTickCount(10);
|
|
|
|
|
axisX->setLabelFormat("%d");
|
|
|
|
|
axisX->setLinePen(QPen(Qt::gray));
|
|
|
|
|
axisX->setLabelsColor(Qt::gray);
|
|
|
|
|
axisX->setMinorTickCount(0); // 隐藏X轴刻度线
|
|
|
|
|
m_chart->addAxis(axisX, Qt::AlignBottom);
|
|
|
|
|
m_series->attachAxis(axisX);
|
|
|
|
|
|
|
|
|
|
// 设置Y轴为百分比
|
|
|
|
|
QValueAxis* axisY = new QValueAxis;
|
|
|
|
|
axisY->setTitleText("占比(%)");
|
|
|
|
|
axisY->setTitleBrush(QBrush(Qt::gray));
|
|
|
|
|
axisY->setLinePen(QPen(Qt::gray));
|
|
|
|
|
axisY->setLabelsColor(Qt::gray); // 设置标签字体颜色为灰色
|
|
|
|
|
axisY->setRange(0, 100);
|
|
|
|
|
axisY->setTitleFont(QFont("Arial", 10)); // 设置标题字体
|
|
|
|
|
axisY->setTitleVisible(true); // 确保标题可见
|
|
|
|
|
m_chart->addAxis(axisY, Qt::AlignLeft);
|
|
|
|
|
m_series->attachAxis(axisY);
|
|
|
|
|
|
|
|
|
|
// 初始化默认数据集
|
|
|
|
|
m_set = new QBarSet("测试1");
|
|
|
|
|
m_set->setColor(QColor(95, 180, 255));
|
|
|
|
|
m_set->setBorderColor(QColor(95, 180, 255));
|
|
|
|
|
QRandomGenerator* generator = QRandomGenerator::global();
|
|
|
|
|
for (int i = 0; i < 300; i++) {
|
|
|
|
|
int randomNumber = generator->bounded(10, 51);
|
|
|
|
|
*m_set << randomNumber;
|
|
|
|
|
}
|
|
|
|
|
m_series->append(m_set);
|
|
|
|
|
|
|
|
|
|
QVBoxLayout* layout = new QVBoxLayout(this);
|
|
|
|
|
layout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
|
layout->setSpacing(0); // 设置间距为0
|
|
|
|
|
layout->addWidget(m_chartView);
|
|
|
|
|
setLayout(layout);
|
2024-11-01 17:40:37 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-12 17:35:54 +08:00
|
|
|
|
void CoalDistributBarChartWidget::setupTimer()
|
|
|
|
|
{
|
|
|
|
|
// 定时器设置
|
|
|
|
|
m_timer = new QTimer(this);
|
|
|
|
|
connect(m_timer, &QTimer::timeout, this,
|
|
|
|
|
&CoalDistributBarChartWidget::updateChart);
|
|
|
|
|
m_timer->start(1000); // 每秒更新一次
|
2024-11-01 17:40:37 +08:00
|
|
|
|
}
|
2024-11-04 18:11:55 +08:00
|
|
|
|
|
2024-11-12 17:35:54 +08:00
|
|
|
|
void CoalDistributBarChartWidget::connectTCPSocket()
|
|
|
|
|
{
|
|
|
|
|
QString ipAddress = m_systemSetting->value("addr/ip").toString();
|
|
|
|
|
quint16 port = m_systemSetting->value("addr/port").toInt();
|
2024-11-04 18:11:55 +08:00
|
|
|
|
|
2024-11-12 17:35:54 +08:00
|
|
|
|
// 连接到 Modbus TCP 服务器
|
|
|
|
|
m_tcpSocket->connectToHost(ipAddress, port);
|
|
|
|
|
if (!m_tcpSocket->waitForConnected(5000)) {
|
|
|
|
|
qDebug() << "连接失败:" << m_tcpSocket->errorString();
|
|
|
|
|
}
|
2024-11-04 18:11:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-12 17:35:54 +08:00
|
|
|
|
int CoalDistributBarChartWidget::getCoalRatioByTCPSocket()
|
|
|
|
|
{
|
|
|
|
|
if (m_tcpSocket->state() != QAbstractSocket::ConnectedState) {
|
|
|
|
|
qDebug() << "未连接到服务器";
|
|
|
|
|
return -1; // 返回错误值
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 构建 Modbus 请求
|
|
|
|
|
const quint8 unitId = 1; // 单元 ID
|
|
|
|
|
const quint8 functionCode = 0x03; // 读保持寄存器
|
|
|
|
|
const quint16 startAddress = 699; // 寄存器地址
|
|
|
|
|
const quint16 registerCount = 1; // 读取寄存器数量
|
|
|
|
|
|
|
|
|
|
// 构建请求数据
|
|
|
|
|
QByteArray request;
|
|
|
|
|
QDataStream stream(&request, QIODevice::WriteOnly);
|
|
|
|
|
stream.setByteOrder(QDataStream::BigEndian); // 使用大端字节序
|
|
|
|
|
|
|
|
|
|
// 添加 Modbus 请求报文各部分
|
|
|
|
|
stream << static_cast<quint16>(0x0004); // 事务 ID
|
|
|
|
|
stream << static_cast<quint16>(0x0000); // 协议 ID
|
|
|
|
|
stream << static_cast<quint16>(0x0006); // 剩余长度
|
|
|
|
|
stream << unitId; // 单元 ID
|
|
|
|
|
stream << functionCode; // 功能码
|
|
|
|
|
stream << static_cast<quint16>(startAddress); // 寄存器地址(700 = 0x01BB)
|
|
|
|
|
stream << registerCount; // 寄存器数量
|
|
|
|
|
|
|
|
|
|
// 发送请求
|
|
|
|
|
m_tcpSocket->write(request);
|
|
|
|
|
if (!m_tcpSocket->waitForBytesWritten(5000)) {
|
|
|
|
|
qDebug() << "写入请求失败:" << m_tcpSocket->errorString();
|
|
|
|
|
return -1; // 返回错误值
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 等待响应
|
|
|
|
|
if (!m_tcpSocket->waitForReadyRead(5000)) {
|
|
|
|
|
qDebug() << "没有收到响应:" << m_tcpSocket->errorString();
|
|
|
|
|
return -1; // 返回错误值
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 读取响应数据
|
|
|
|
|
QByteArray response = m_tcpSocket->readAll();
|
|
|
|
|
if (response.size() < 9) {
|
|
|
|
|
qDebug() << "响应数据不完整";
|
|
|
|
|
return -1; // 返回错误值
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 解析响应
|
|
|
|
|
QDataStream responseStream(response);
|
|
|
|
|
responseStream.setByteOrder(QDataStream::LittleEndian);
|
|
|
|
|
quint16 responseTransactionId;
|
|
|
|
|
responseStream >> responseTransactionId; // 事务 ID
|
|
|
|
|
quint16 responseProtocolId;
|
|
|
|
|
responseStream >> responseProtocolId; // 协议 ID
|
|
|
|
|
quint16 responseLength;
|
|
|
|
|
responseStream >> responseLength; // 剩余长度
|
|
|
|
|
quint8 responseUnitId;
|
|
|
|
|
responseStream >> responseUnitId; // 单元 ID
|
|
|
|
|
quint8 responseFunctionCode;
|
|
|
|
|
responseStream >> responseFunctionCode; // 功能码
|
|
|
|
|
quint8 byteCount;
|
|
|
|
|
responseStream >> byteCount; // 字节计数
|
|
|
|
|
|
|
|
|
|
// 检查功能码和字节计数
|
|
|
|
|
if (responseFunctionCode != functionCode || byteCount != 2) {
|
|
|
|
|
qDebug() << "功能码或字节计数不匹配";
|
|
|
|
|
return -1; // 返回错误值
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取并输出最后四个字节
|
|
|
|
|
if (response.size() < 2) {
|
|
|
|
|
qDebug() << "响应数据少于四个字节,无法获取最后四位";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QByteArray lastFourBytes = response.right(2); // 获取最后2个字节
|
|
|
|
|
|
|
|
|
|
bool isOk;
|
|
|
|
|
int decimalValue = lastFourBytes.toHex().toInt(&isOk, 16);
|
|
|
|
|
|
|
|
|
|
return decimalValue; // 返回煤量占比
|
2024-11-04 18:11:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-12 17:35:54 +08:00
|
|
|
|
QByteArray CoalDistributBarChartWidget::createModbusTcpRequest()
|
|
|
|
|
{
|
|
|
|
|
QByteArray request;
|
|
|
|
|
QDataStream stream(&request, QIODevice::WriteOnly);
|
|
|
|
|
stream.setByteOrder(QDataStream::BigEndian); // 使用大端字节序
|
|
|
|
|
|
|
|
|
|
// 构建 Modbus TCP 请求
|
|
|
|
|
quint16 transactionId = 0x0004; // 事务 ID
|
|
|
|
|
quint16 protocolId = 0x0000; // 协议 ID
|
|
|
|
|
quint16 length = 0x0006; // 剩余长度
|
|
|
|
|
quint8 unitId = 0x01; // 单元 ID
|
|
|
|
|
quint8 functionCode = 0x03; // 功能码
|
|
|
|
|
quint8 byteCount = 0x02; // 字节计数
|
|
|
|
|
quint16 registerAddress = 0x01BB; // 寄存器地址 700
|
|
|
|
|
quint16 registerCount = 0x0001; // 寄存器数量
|
|
|
|
|
|
|
|
|
|
// 写入数据
|
|
|
|
|
stream << transactionId;
|
|
|
|
|
stream << protocolId;
|
|
|
|
|
stream << length;
|
|
|
|
|
stream << unitId;
|
|
|
|
|
stream << functionCode;
|
|
|
|
|
stream << byteCount;
|
|
|
|
|
stream << registerAddress;
|
|
|
|
|
stream << registerCount;
|
|
|
|
|
|
|
|
|
|
return request; // 返回生成的请求报文
|
2024-11-04 18:11:55 +08:00
|
|
|
|
}
|