#include "mainwindow.h" #include "ui_mainwindow.h" #include #include #include #include #include #include #include #include #include #include #include #include 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 baudRateRow; baudRateRow << new QStandardItem("波特率") << new QStandardItem(QString::number(config.baudRate)); m_serial_settingsModel->appendRow(baudRateRow); QList dataBitsRow; dataBitsRow << new QStandardItem("数据位") << new QStandardItem(QString::number(config.dataBits)); m_serial_settingsModel->appendRow(dataBitsRow); QList parityRow; parityRow << new QStandardItem("校验") << new QStandardItem(QString::number(config.parity)); m_serial_settingsModel->appendRow(parityRow); QList stopBitsRow; stopBitsRow << new QStandardItem("停止位") << new QStandardItem(QString::number(config.stopBits)); m_serial_settingsModel->appendRow(stopBitsRow); QList 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 rawData = m_busCore->queryRawData(deviceId, startTime, endTime); for (const QByteArray &data : rawData) { QList row; // 时间戳是数据的前8个字节 qint64 timestamp = *reinterpret_cast(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 messages = m_busCore->queryBusMessages(source, "data_processor", startTime, endTime); for (const BusMessage &msg : messages) { QList 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("%1 [发送] %2") .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("%1 串口%2 [接收] %3") .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); }