251 lines
7.7 KiB
C++
251 lines
7.7 KiB
C++
#include "coaldistributbarchartwidget.h"
|
||
|
||
#include <QDateTimeAxis>
|
||
#include <QList>
|
||
#include <QRandomGenerator>
|
||
#include <QScopedPointer>
|
||
#include <QTcpSocket>
|
||
#include <QVBoxLayout>
|
||
#include <QtCharts/QChart>
|
||
|
||
#include <QBarSeries>
|
||
#include <QBarSet>
|
||
#include <QChart>
|
||
#include <QChartView>
|
||
#include <QColor>
|
||
#include <QDateTimeAxis>
|
||
#include <QTimer>
|
||
#include <QVBoxLayout>
|
||
|
||
#include <memory>
|
||
|
||
CoalDistributBarChartWidget::CoalDistributBarChartWidget(QWidget* parent)
|
||
: QWidget(parent)
|
||
, m_tcpSocket(new QTcpSocket(this))
|
||
{
|
||
initializeChart();
|
||
|
||
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 > 100) {
|
||
return;
|
||
}
|
||
|
||
int setCount = m_set->count();
|
||
|
||
qDebug() << "setCount" << setCount;
|
||
|
||
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 = "192.168.80.101"; // 替换为实际 IP 地址
|
||
quint16 port = 3000; // Modbus TCP 端口
|
||
|
||
// 连接到 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<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; // 返回错误值
|
||
}
|
||
|
||
qDebug() << "response" << response.toHex();
|
||
|
||
// 解析响应
|
||
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);
|
||
qDebug() << "最后四位:" << decimalValue;
|
||
|
||
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; // 返回生成的请求报文
|
||
}
|