#include "coaldistributbarchartwidget.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include CoalDistributBarChartWidget::CoalDistributBarChartWidget(QWidget* parent) : QWidget(parent) , m_tcpSocket(new QTcpSocket(this)) { initializeChart(); m_systemSetting = new QSettings("system.ini", QSettings::IniFormat); connectTCPSocket(); setupTimer(); } CoalDistributBarChartWidget::~CoalDistributBarChartWidget() { if (m_tcpSocket->state() == QAbstractSocket::ConnectedState) { m_tcpSocket->disconnectFromHost(); m_tcpSocket->waitForDisconnected(); } delete m_tcpSocket; } void CoalDistributBarChartWidget::updateChart() { int radio = getCoalRatioByTCPSocket(); if (radio < 0 || radio > 90) { return; } int setCount = m_set->count(); m_set->remove(setCount - 1); m_set->insert(0, radio); } 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); } void CoalDistributBarChartWidget::setupTimer() { // 定时器设置 m_timer = new QTimer(this); connect(m_timer, &QTimer::timeout, this, &CoalDistributBarChartWidget::updateChart); m_timer->start(1000); // 每秒更新一次 } void CoalDistributBarChartWidget::connectTCPSocket() { QString ipAddress = m_systemSetting->value("addr/ip").toString(); quint16 port = m_systemSetting->value("addr/port").toInt(); // 连接到 Modbus TCP 服务器 m_tcpSocket->connectToHost(ipAddress, port); if (!m_tcpSocket->waitForConnected(5000)) { qDebug() << "连接失败:" << m_tcpSocket->errorString(); } } 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(0x0004); // 事务 ID stream << static_cast(0x0000); // 协议 ID stream << static_cast(0x0006); // 剩余长度 stream << unitId; // 单元 ID stream << functionCode; // 功能码 stream << static_cast(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; // 返回煤量占比 } 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; // 返回生成的请求报文 }