| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342 |
- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- #include <QVBoxLayout>
- #include <QHBoxLayout>
- #include <QSplitter>
- #include <QListView>
- #include <QTableView>
- #include <QHeaderView>
- #include <QDateTime>
- #include <QDebug>
- #include <QItemSelectionModel>
- #include <QtCharts/QDateTimeAxis>
- #include <QtCharts/QValueAxis>
- #include <QMessageBox>
- MainWindow::MainWindow(QWidget *parent)
- : QMainWindow(parent),
- ui(new Ui::MainWindow),
- m_busCore(new SoftBusCore(this)),
- m_serialManager(new SerialManager(m_busCore, this)),
- m_dataTable(new QTableView(this)),
- m_serial_settingsModel(new QStandardItemModel(this)),
- m_deviceModel(new QStandardItemModel(this)),
- m_dataModel(new QStandardItemModel(this)),
- m_dataSeries(new QLineSeries())
- {
- ui->setupUi(this);
- // 初始化系统
- initializeSystem();
- // 创建UI
- createUI();
- // 创建连接
- createConnections();
- // 启动串口监控
- m_serialManager->startDiscovery();
- // 更新设备列表
- updateDeviceList();
- }
- MainWindow::~MainWindow()
- {
- // 停止串口监控
- m_serialManager->stopDiscovery();
- }
- void MainWindow::initializeSystem()
- {
- // 初始化数据库
- if (!m_busCore->initDB("raw_db", "bus_db"))
- {
- qCritical() << "Failed to initialize database";
- }
- // 注册串口设备
- foreach (const QString &portName, m_serialManager->getAvailablePorts())
- {
- DeviceInfo device;
- device.id = portName;
- device.type = "serial";
- device.address = portName;
- device.protocol = "modbus"; // 默认协议
- m_busCore->registerDevice(device);
- }
- }
- void MainWindow::createUI()
- {
- // 左侧设备列表
- ui->listV_device->setModel(m_deviceModel);
- // 右侧数据表格(上方为配置表格 ,下方为图表) )
- ui->tableV_serial_set->setModel(m_serial_settingsModel);
- ui->tableV_serial_set->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
- m_serial_settingsModel->setHorizontalHeaderLabels({"参数", "值"});
- SerialManager::SerialConfig config = m_serialManager->getSerialConfig();
- QList<QStandardItem *> baudRateRow;
- baudRateRow << new QStandardItem("波特率") << new QStandardItem(QString::number(config.baudRate));
- m_serial_settingsModel->appendRow(baudRateRow);
- QList<QStandardItem *> dataBitsRow;
- dataBitsRow << new QStandardItem("数据位") << new QStandardItem(QString::number(config.dataBits));
- m_serial_settingsModel->appendRow(dataBitsRow);
- QList<QStandardItem *> parityRow;
- parityRow << new QStandardItem("校验") << new QStandardItem(QString::number(config.parity));
- m_serial_settingsModel->appendRow(parityRow);
- QList<QStandardItem *> stopBitsRow;
- stopBitsRow << new QStandardItem("停止位") << new QStandardItem(QString::number(config.stopBits));
- m_serial_settingsModel->appendRow(stopBitsRow);
- QList<QStandardItem *> flowControlRow;
- flowControlRow << new QStandardItem("流控") << new QStandardItem(QString::number(config.flowControl));
- m_serial_settingsModel->appendRow(flowControlRow);
- // Raw Data Table
- ui->tableV_raw_data->setModel(m_dataModel);
- m_dataModel->setHorizontalHeaderLabels({"时间", "来源", "协议", "数据"});
- ui->tableV_raw_data->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
- ui->tableV_raw_data->setEditTriggers(QAbstractItemView::NoEditTriggers);
- ui->tableV_raw_data->setSelectionBehavior(QAbstractItemView::SelectRows);
- ui->tableV_raw_data->setSelectionMode(QAbstractItemView::SingleSelection);
- // ui->tableV_bus_data->setModel();
- }
- void MainWindow::createConnections()
- {
- // 设备注册/注销信号
- connect(m_busCore, &SoftBusCore::deviceRegistered, this, &MainWindow::updateDeviceList);
- connect(m_busCore, &SoftBusCore::deviceUnregistered, this, &MainWindow::updateDeviceList);
- // 总线消息存储信号
- connect(m_busCore, &SoftBusCore::busMessageStored, this, &MainWindow::updateChart);
- // 设备选择信号
- connect(ui->listV_device->selectionModel(), &QItemSelectionModel::currentChanged,this, &MainWindow::onDeviceSelected);
- // 串口管理器信号
- connect(m_serialManager, &SerialManager::portDiscovered, this, [this](const QString &portName, const QString &desc)
- {
- Q_UNUSED(desc);
- updateDeviceList(); });
- connect(m_serialManager, &SerialManager::portRemoved, this, [this](const QString &portName)
- { updateDeviceList(); });
- connect(m_serialManager, &SerialManager::dataReceived, this, &MainWindow::onSerialDataReceived);
- }
- void MainWindow::updateDeviceList()
- {
- m_deviceModel->clear();
- // 添加串口设备
- foreach (const QString &portName, m_serialManager->getAvailablePorts())
- {
- QStandardItem *item = new QStandardItem("串口: " + portName);
- item->setData(portName, Qt::UserRole);
- m_deviceModel->appendRow(item);
- }
- // 添加其他类型设备(CAN、以太网等)
- // ...
- }
- void MainWindow::onDeviceSelected(const QModelIndex &index)
- {
- if (index.isValid())
- {
- // 显示设备相关数据
- QString deviceId = index.data(Qt::UserRole).toString();
- m_currentDeviceId = deviceId;
- m_serialManager->openSerialPort(QSerialPortInfo(deviceId));
- showRawData(deviceId);
- showBusMessages(deviceId);
- }
- }
- void MainWindow::showRawData(const QString &deviceId)
- {
- m_dataModel->removeRows(0, m_dataModel->rowCount());
- // 查询最近10分钟的原始数据
- qint64 endTime = QDateTime::currentMSecsSinceEpoch();
- qint64 startTime = endTime - 10 * 60 * 1000;
- QList<QByteArray> rawData = m_busCore->queryRawData(deviceId, startTime, endTime);
- for (const QByteArray &data : rawData)
- {
- QList<QStandardItem *> row;
- // 时间戳是数据的前8个字节
- qint64 timestamp = *reinterpret_cast<const qint64 *>(data.constData());
- row << new QStandardItem(QDateTime::fromMSecsSinceEpoch(timestamp).toString("hh:mm:ss"));
- row << new QStandardItem(deviceId);
- row << new QStandardItem("RAW");
- row << new QStandardItem(data.mid(8).toHex());
- m_dataModel->appendRow(row);
- }
- }
- void MainWindow::showBusMessages(const QString &source)
- {
- // 查询最近10分钟的总线消息
- qint64 endTime = QDateTime::currentMSecsSinceEpoch();
- qint64 startTime = endTime - 10 * 60 * 1000;
- QList<BusMessage> messages = m_busCore->queryBusMessages(source, "data_processor", startTime, endTime);
- for (const BusMessage &msg : messages)
- {
- QList<QStandardItem *> row;
- row << new QStandardItem(QDateTime::fromMSecsSinceEpoch(msg.timestamp).toString("hh:mm:ss"));
- row << new QStandardItem(msg.source);
- row << new QStandardItem(msg.payload["protocol"].toString());
- QString dataStr;
- if (msg.payload["protocol"] == "modbus")
- {
- dataStr = QString("ID:%1 FN:%2")
- .arg(msg.payload["slave_id"].toInt())
- .arg(msg.payload["function_code"].toInt());
- }
- else
- {
- dataStr = msg.payload["raw_data"].toString();
- }
- row << new QStandardItem(dataStr);
- m_dataModel->appendRow(row);
- }
- }
- void MainWindow::updateChart(const BusMessage &message)
- {
- if (message.payload["protocol"] != "modbus")
- return;
- // 解析Modbus数据并更新图表
- QJsonArray dataArray = message.payload["data"].toArray();
- if (dataArray.size() > 0)
- {
- double value = dataArray[0].toDouble();
- qint64 timestamp = message.timestamp;
- m_dataSeries->append(timestamp, value);
- // 限制图表显示的数据点数量
- if (m_dataSeries->count() > 100)
- {
- m_dataSeries->removePoints(0, m_dataSeries->count() - 100);
- }
- }
- }
- // btn_fun
- // QCheckBox *checkBox_serial_hex;
- // QCheckBox *checkBox_serial_ascii;
- // QTextEdit *textEdit_serial;
- // QPushButton *btn_serial_clear;
- // QPushButton *btn_serial_send;
- void MainWindow::on_btn_serial_clear_clicked()
- {
- ui->textEdit_serial->clear();
- }
- void MainWindow::on_btn_serial_clear_send_clicked()
- {
- ui->lineEdit_serial_send->clear();
- }
- // 发送串口数据
- void MainWindow::on_btn_serial_send_clicked()
- {
- if (!m_serialManager->isPortOpen(m_currentDeviceId)) {
- QMessageBox::warning(this, "串口未打开", "请先打开串口设备");
- return;
- }
- QString dataToSend = ui->lineEdit_serial_send->text();
- if (dataToSend.isEmpty()) {
- QMessageBox::information(this, "发送数据", "请输入要发送的数据");
- return;
- }
- // 根据当前显示模式处理数据
- if (ui->checkBox_serial_hex->isChecked()) {
- // 十六进制模式 - 将输入视为十六进制字符串
- QByteArray hexData = QByteArray::fromHex(dataToSend.toLatin1());
- m_serialManager->writeData(m_currentDeviceId,hexData);
- } else {
- // ASCII模式 - 直接发送文本
- m_serialManager->writeData(m_currentDeviceId,dataToSend.toUtf8());
- }
- // 在接收区显示发送的数据(带发送标记)
- QString timestamp = QDateTime::currentDateTime().toString("[hh:mm:ss]");
- ui->textEdit_serial->append(QString("<span style='color:blue;'>%1 [发送] %2</span>")
- .arg(timestamp)
- .arg(dataToSend));
- // 清空发送输入框
- // ui->lineEdit_serial_send->clear();
- }
- // 处理接收到的串口数据
- void MainWindow::onSerialDataReceived(const QString &portName, const QByteArray &data)
- {
- QString displayData;
- QString timestamp = QDateTime::currentDateTime().toString("[hh:mm:ss]");
- if (ui->checkBox_serial_hex->isChecked()) {
- // 十六进制显示
- displayData = data.toHex(' ').toUpper();
- } else {
- // ASCII显示
- displayData = QString::fromUtf8(data);
- // 替换控制字符为可见表示
- displayData.replace('\r', "\\r");
- displayData.replace('\n', "\\n");
- displayData.replace('\t', "\\t");
- }
- ui->textEdit_serial->append(QString("<span style='color:green;'>%1 串口%2 [接收] %3</span>")
- .arg(timestamp)
- .arg(portName)
- .arg(displayData));
- }
- // 切换显示模式
- void MainWindow::on_checkBox_serial_hex_toggled(bool checked)
- {
- ui->checkBox_serial_ascii->setChecked(!checked);
- // 重新显示当前内容
- QString currentText = ui->textEdit_serial->toPlainText();
- ui->textEdit_serial->clear();
- ui->textEdit_serial->setText(currentText);
- }
- void MainWindow::on_checkBox_serial_ascii_toggled(bool checked)
- {
- ui->checkBox_serial_hex->setChecked(!checked);
- // 重新显示当前内容
- QString currentText = ui->textEdit_serial->toPlainText();
- ui->textEdit_serial->clear();
- ui->textEdit_serial->setText(currentText);
- }
|