#include "mainwindow.h" #include "ui_mainwindow.h" #include #include #include #include #include #include "keyphase.h" #include "singlerelay.h" #include "tachometer.h" #include "seismic_monitor.h" #include "setpoint.h" #include #include #include #include #include #include #include "relaysetting.h" #include "config_mgr.h" #include "vibrationdata.h" QString g_strServerIp; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); QMenuBar *menuBar = this->menuBar(); this->setMenuBar(menuBar); //添加到对象树 menuBar->addMenu(ui->menu_tool); ui->widget_body->setProperty("flag", "title"); ui->menuBar->setProperty("flag", "menuBar"); //关联事件过滤器用于双击放大 ui->widget_body->installEventFilter(this); ui->widget_body->setProperty("flag", "body"); ui->statusBar->setProperty("flag", "status"); // 创建进度条 progressBar = new QProgressBar(this); // 设置进度条的范围(0到100) progressBar->setRange(0, 100); // 将进度条添加到状态栏 statusBar()->addWidget(progressBar); progressBar->setVisible(false); // 初始隐藏 progressBar->setFixedWidth(300); //this->initStyle(); //添加信号槽 QObject::connect(ui->action_realy, &QAction::triggered, this, &MainWindow::onMenuAction_relay); slot_no = -1; btnGroup_slot = new QButtonGroup(this); btnGroup_slot->addButton(ui->pushButton_slot0); btnGroup_slot->addButton(ui->pushButton_slot1); btnGroup_slot->addButton(ui->pushButton_slot2); btnGroup_slot->addButton(ui->pushButton_slot3); btnGroup_slot->addButton(ui->pushButton_slot4); btnGroup_slot->addButton(ui->pushButton_slot5); btnGroup_slot->addButton(ui->pushButton_slot6); btnGroup_slot->addButton(ui->pushButton_slot7); btnGroup_slot->addButton(ui->pushButton_slot8); btnGroup_slot->addButton(ui->pushButton_slot9); btnGroup_slot->addButton(ui->pushButton_slot10); btnGroup_slot->addButton(ui->pushButton_slot11); btnGroup_slot->addButton(ui->pushButton_slot12); btnGroup_slot->addButton(ui->pushButton_slot13); btnGroup_slot->addButton(ui->pushButton_slot14); btnGroup_slot->addButton(ui->pushButton_slot15); list_label.reserve(16); list_label.push_back(ui->label_18); list_label.push_back(ui->label_1); list_label.push_back(ui->label_2); list_label.push_back(ui->label_3); list_label.push_back(ui->label_4); list_label.push_back(ui->label_5); list_label.push_back(ui->label_6); list_label.push_back(ui->label_7); list_label.push_back(ui->label_8); list_label.push_back(ui->label_9); list_label.push_back(ui->label_10); list_label.push_back(ui->label_11); list_label.push_back(ui->label_12); list_label.push_back(ui->label_13); list_label.push_back(ui->label_14); list_label.push_back(ui->label_15); ui->pushButton_slot->setChecked(true); createMenu(); connect(btnGroup_slot, SIGNAL(buttonClicked(QAbstractButton *)), this, SLOT(OnButtonGroup(QAbstractButton *))); QSettings settingsread(QCoreApplication::applicationDirPath() + "\\config\\config.ini", QSettings::IniFormat); g_strServerIp = settingsread.value("Server/IP").toString(); connectServer(); // 设置自定义日志处理函数 #ifndef QT_DEBUG qInstallMessageHandler(messageHandler); #endif } MainWindow::~MainWindow() { delete ui; } void MainWindow::onDisConnected() { statusBar()->showMessage("连接失败!正在重连……", 3000); // 显示3秒 } void MainWindow::onConnected() { statusBar()->showMessage("连接成功!", 3000); // 显示3秒 } void MainWindow::connectServer() { m_tcpClient = MyTcpClient::instance(); // 监听信号 connect(m_tcpClient, SIGNAL(dataReceived(const QByteArray &)), this, SLOT(readData(const QByteArray &))); connect(m_tcpClient, SIGNAL(disconnected()), this, SLOT(onDisConnected())); connect(m_tcpClient, SIGNAL(connected()), this, SLOT(onConnected())); // 连接服务器 m_tcpClient->connectToServer(g_strServerIp, 10000); } void MainWindow::initStyle() { //加载样式表 QString qss; QFile file(":/qss/soft.css"); if (file.open(QFile::ReadOnly)) { qss = QLatin1String(file.readAll()); QString paletteColor = qss.mid(20, 7); qApp->setPalette(QPalette(paletteColor)); qApp->setStyleSheet(qss); file.close(); } } void MainWindow::readJsonFile(const QString &filePath) { // 创建文件对象 QFile file(filePath); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { qDebug() << "Cannot open file for reading:" << filePath; return; } QString content = file.readAll(); file.close(); QByteArray jsonData = content.toUtf8(); QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData); if (jsonDoc.isNull()) { qDebug() << "Cannot parse JSON document"; return; } if (!jsonDoc.isObject() && !jsonDoc.isArray()) { qDebug() << "JSON document is not an object or an array"; return; } int slot_id = 0; QJsonArray jsonArray = jsonDoc.array(); for (const QJsonValue &value : jsonArray) { SlotConfig slot_config; if (value.isObject()) { // 处理数组中的对象,例如每个对象代表一个记录或用户等。 QJsonObject obj = value.toObject(); slot_config.slot = obj["slot"].toInt(); slot_config.slot_type = obj["slot_type"].toString(); slot_config.chan_display = obj["chan_display"].toString(); slot_config.rack_type = obj["rack_type"].toString(); map_slot_config.insert(slot_id, slot_config); slot_id ++; } } } void MainWindow::createMenu() { QList buttonList = btnGroup_slot->buttons(); for (int i = 0; i < buttonList.count(); i++) { createMenu(QString("%1").arg(i + 1), (QPushButton *)buttonList[i]); map_slot_config[i].slot_btn = (QPushButton *)buttonList[i]; map_slot_config[i].slot_label = list_label[i]; std::shared_ptr base_ptr = ConfigMgr::Instance()->GetSlotPtr(i); if(base_ptr != nullptr){ switch (base_ptr->card_type_) { case kCardVibSingle : buttonList[i]->setText("振动"); break; default: break; } } } } void MainWindow::createMenu(const QString &rootTitle, QPushButton *parent) { // 创建主菜单 QMenu *mainMenu = new QMenu(rootTitle, parent); // 创建第一层子菜单 QMenu *monitors = new QMenu("监视器", mainMenu); QMenu *relays = new QMenu("/DOM810 继电器模块", mainMenu); QMenu *keyphasor = new QMenu("/KPM834 键相模块", mainMenu); // 创建第二层子菜单:/HAM824 振动板卡 QMenu *proximitor_menu = new QMenu("/HAM824 振动板卡", monitors); QMenu *rpm_menu = new QMenu("/OPM844 转速板卡", monitors); // 创建第三层子菜单:/HAM824 单板卡、三冗余板卡 QAction *proximitor_1 = proximitor_menu->addAction("/HAM824 单板卡"); proximitor_1->setData(kCardVibSingle); QAction *proximitor_2 = proximitor_menu->addAction("/HAM824 三冗余板卡"); proximitor_2->setData(kCardVibTMRPrimary); QAction *rpm_1 = rpm_menu->addAction("/OPM844 单板卡"); rpm_1->setData(kCardSpeedSingle); // 创建第二层子菜单:/KPM834 键相模块 QAction *keyphasor_1 = keyphasor->addAction("/KPM834 单板卡"); keyphasor_1->setData(kCardKeyphaseSingle); QAction *keyphasor_2 = keyphasor->addAction("/KPM834 两板卡"); keyphasor_2->setData(kCardKeyphaseDouble); // 创建第二层子菜单:/DOM810 继电器模块 QAction *relays_1 = relays->addAction("/DOM810 单板卡"); relays_1->setData(kCardRelaySingle); QAction *relays_2 = relays->addAction("/DOM810 三冗余板卡"); relays_2->setData(kCardRelayTMRPrimary); // 将子菜单加入上一级菜单 monitors->addMenu(proximitor_menu); // 将第二层加入第一层 monitors->addMenu(rpm_menu); // 第二层另一个子菜单 mainMenu->addMenu(monitors); // 将第一层加入主菜单 mainMenu->addMenu(relays); mainMenu->addMenu(keyphasor); QAction *reset = mainMenu->addAction("重置模块"); QAction *upgrade = mainMenu->addAction("升级固件"); QAction *version = mainMenu->addAction("查看版本"); // 绑定 **鼠标事件过滤器**,确保只响应右键 // 设置右键菜单策略 parent->setContextMenuPolicy(Qt::CustomContextMenu); // 使用 `customContextMenuRequested` 事件,确保只有右键点击时弹出菜单 connect(parent, &QPushButton::customContextMenuRequested, this, [ = ](const QPoint &pos) { qDebug() << "右键菜单触发1:" << pos; // 弹出菜单并捕获右键点击 mainMenu->exec(QCursor::pos()); mainMenu->close(); }); // 连接所有菜单项 QObject::connect(proximitor_1, &QAction::triggered, this, &MainWindow::onMenuActionTriggered); QObject::connect(proximitor_2, &QAction::triggered, this, &MainWindow::onMenuActionTriggered); QObject::connect(rpm_1, &QAction::triggered, this, &MainWindow::onMenuActionTriggered); QObject::connect(relays_1, &QAction::triggered, this, &MainWindow::onMenuActionTriggered); QObject::connect(relays_2, &QAction::triggered, this, &MainWindow::onMenuActionTriggered); QObject::connect(keyphasor_1, &QAction::triggered, this, &MainWindow::onMenuActionTriggered); QObject::connect(keyphasor_2, &QAction::triggered, this, &MainWindow::onMenuActionTriggered); QObject::connect(reset, &QAction::triggered, this, &MainWindow::onMenuActionTriggered); QObject::connect(upgrade, &QAction::triggered, this, &MainWindow::onMenuActionTriggered); QObject::connect(version, &QAction::triggered, this, &MainWindow::onMenuActionTriggered); } void MainWindow::createMenuSet(const QString &rootTitle, QPushButton *parent) { // 创建主菜单 qDebug() << "createMenu" << parent->objectName() ; QMenu *mainMenu = new QMenu(rootTitle, parent); QAction *option = mainMenu->addAction("通道配置…"); QAction *set_points = mainMenu->addAction("触发配置…"); QAction *point_names = mainMenu->addAction("测点名称"); } // 清除菜单中所有动作的属性 void MainWindow::clearMenuProperties(QMenu *menu) { // 遍历菜单的所有动作 if (!menu) { qWarning() << "菜单为空,无法清除属性!"; return; } // 遍历菜单的所有动作 for (QAction *action : menu->actions()) { if (!action) { continue; } // 检查是否有子菜单 if (QMenu *subMenu = action->menu()) { clearMenuProperties(subMenu); // 递归处理子菜单 } // 清除动作的属性 action->setProperty("customProperty", QVariant()); qDebug() << "清除了属性,动作:" << action->text(); } } void MainWindow::onMenuActionTriggered() { qDebug() << "onMenuActionTriggered()" ; QAction *action = qobject_cast(sender()); if (action) { // 获取触发动作的父菜单 QMenu *menu = qobject_cast(action->parent()); // 遍历所有父菜单,直到找到按钮 while (menu) { QPushButton *button = qobject_cast(menu->parent()); if (button) { qDebug() << "子菜单项被点击,所属按钮:" << button->objectName() << action->text(); QString slot_type = action->text().mid(1, 6); QString rack_type = action->text().right(action->text().length() - 8); qDebug() << "rack_type" << action->data(); card_type = static_cast(action->data().toInt()); int button_id = button->objectName().right(button->objectName().length() - 15).toInt(); qDebug() << slot_type << rack_type << button_id << map_slot_config[button_id + 1].slot_type << map_slot_config[button_id + 2].slot_type ; map_slot_config[button_id].slot_label->setStyleSheet("QLabel { color :#2980b9; font: bold 16px}"); QString chan_display = ""; if (slot_type == "DOM810") { chan_display = "继电器"; } else if (slot_type == "KPM834") { chan_display = "键相"; } else if (slot_type == "HAM824") { chan_display = "振动"; } else if (slot_type == "OPM844") { chan_display = "转速"; } if (rack_type == "三冗余板卡" && (map_slot_config[button_id].slot_type != "" || map_slot_config[button_id + 1].slot_type != "" \ || map_slot_config[button_id + 2].slot_type != "")) { QMessageBox::information(this, QStringLiteral("提示"), "不要重叠三冗余板卡配置,请在创建新配置之前移除现有的配置!"); return; } else if (rack_type == "三冗余板卡" && map_slot_config[button_id + 1].slot_type == "" \ && map_slot_config[button_id + 2].slot_type == "") { map_slot_config[button_id].slot_type = slot_type; map_slot_config[button_id].rack_type = "TMR1"; map_slot_config[button_id].slot_btn->setText(chan_display); map_slot_config[button_id].chan_display = chan_display; map_slot_config[button_id + 1].slot_type = slot_type; map_slot_config[button_id + 1].rack_type = "TMR2"; map_slot_config[button_id + 1].slot_btn->setText(chan_display); map_slot_config[button_id + 1].chan_display = chan_display; map_slot_config[button_id + 2].slot_type = slot_type; map_slot_config[button_id + 2].rack_type = "TMR3"; map_slot_config[button_id + 2].slot_btn->setText(chan_display); map_slot_config[button_id + 2].chan_display = chan_display; } if (rack_type == "两板卡" && (map_slot_config[button_id].slot_type != "" || map_slot_config[button_id + 1].slot_type != "")) { QMessageBox::information(this, QStringLiteral("提示"), "不要重叠两板卡配置,请在创建新配置之前移除现有的配置!"); return; } else if (rack_type == "两板卡" && map_slot_config[button_id + 1].slot_type == "") { map_slot_config[button_id].slot_type = slot_type; map_slot_config[button_id].rack_type = "Double1"; map_slot_config[button_id].slot_btn->setText(chan_display); map_slot_config[button_id].chan_display = chan_display; map_slot_config[button_id + 1].slot_type = slot_type; map_slot_config[button_id + 1].rack_type = "Double2"; map_slot_config[button_id + 1].slot_btn->setText(chan_display); map_slot_config[button_id + 1].chan_display = chan_display; } if (rack_type == "单板卡" && map_slot_config[button_id].slot_type != "") { QMessageBox::information(this, QStringLiteral("提示"), "不要重叠单板卡配置,请在创建新配置之前移除现有的配置!"); return; } else if (rack_type == "单板卡" && map_slot_config[button_id].slot_type == "") { map_slot_config[button_id].slot_type = slot_type; map_slot_config[button_id].rack_type = "Single"; map_slot_config[button_id].chan_display = chan_display; button->setText(chan_display); } if (action->text() == "重置模块") { if (ConfigMgr::Instance()->card_type_[button_id - 1] == kCardRelayTMRPrimary) { map_slot_config[button_id].slot_type = ""; map_slot_config[button_id].rack_type = "0"; map_slot_config[button_id].slot_btn->setText(""); map_slot_config[button_id].chan_display = ""; map_slot_config[button_id + 1].slot_type = ""; map_slot_config[button_id + 1].rack_type = "0"; map_slot_config[button_id + 1].slot_btn->setText(""); map_slot_config[button_id + 1].chan_display = ""; map_slot_config[button_id + 2].slot_type = ""; map_slot_config[button_id + 2].rack_type = "0"; map_slot_config[button_id + 2].slot_btn->setText(""); map_slot_config[button_id + 2].chan_display = ""; } else if (ConfigMgr::Instance()->card_type_[button_id - 1] == kCardRelayTMRBackup) { map_slot_config[button_id - 1].slot_type = ""; map_slot_config[button_id - 1].rack_type = "0"; map_slot_config[button_id - 1].slot_btn->setText(""); map_slot_config[button_id - 1].chan_display = ""; map_slot_config[button_id].slot_type = ""; map_slot_config[button_id].rack_type = "0"; map_slot_config[button_id].slot_btn->setText(""); map_slot_config[button_id].chan_display = ""; map_slot_config[button_id + 1].slot_type = ""; map_slot_config[button_id + 1].rack_type = "0"; map_slot_config[button_id + 1].slot_btn->setText(""); map_slot_config[button_id + 1].chan_display = ""; }else if (ConfigMgr::Instance()->card_type_[button_id - 1] == kCardVibSingle || ConfigMgr::Instance()->card_type_[button_id - 1] == kCardSpeedSingle || ConfigMgr::Instance()->card_type_[button_id - 1] == kCardKeyphaseSingle) { ConfigMgr::Instance()->card_type_[button_id - 1] = kCardNone; map_slot_config[button_id].slot_btn->setText(""); } } else if (action->text() == "升级固件") { sendUpgradePackage(button_id); } else if (action->text() == "查看版本") { getVersion(button_id); } break; // 找到按钮后,跳出循环 } // 如果没有找到按钮,继续向上查找 menu = qobject_cast(menu->parent()); } } } void MainWindow::OnButtonGroup(QAbstractButton *slot_btn) { if (slot_btn != NULL && ui->pushButton_chan->isChecked()) { QString object_name = slot_btn->objectName(); qDebug() << object_name ; int button_id = object_name.right(object_name.length() - 15).toInt(); SlotConfig slot_config = map_slot_config[button_id]; map_slot_config[button_id].slot_label->setStyleSheet("QLabel { color :#2980b9; font: bold 16px}"); std::shared_ptr base_ptr = ConfigMgr::Instance()->GetSlotPtr(button_id); if(base_ptr == nullptr){ ConfigMgr::Instance()->card_type_[button_id - 1] = card_type; if (slot_config.slot_type == "KPM834") { // 键相模块 KeyPhase *key_phase = new KeyPhase(button_id,card_type); key_phase->setWindowModality(Qt::ApplicationModal); key_phase->show(); } else if (slot_config.slot_type == "DOM810") { // 继电器模块 SingleRelay *single_relay = new SingleRelay(); single_relay->setWindowModality(Qt::ApplicationModal); single_relay->show(); } else if (slot_config.slot_type == "HAM824") { // 振动模块 Seismic_monitor *seismic_monitor = new Seismic_monitor(button_id,card_type); seismic_monitor->setWindowModality(Qt::ApplicationModal); seismic_monitor->show(); } else if (slot_config.slot_type == "OPM844") { // 转速模块 Tachometer *tachometer = new Tachometer(button_id,card_type); tachometer->setWindowModality(Qt::ApplicationModal); tachometer->show(); } return; } switch(base_ptr->card_type_){ case kCardVibSingle:{ Seismic_monitor *seismic_monitor = new Seismic_monitor(button_id,card_type); seismic_monitor->setWindowModality(Qt::ApplicationModal); seismic_monitor->show(); break; } case kCardKeyphaseSingle:{ KeyPhase *key_phase = new KeyPhase(button_id,card_type); key_phase->setWindowModality(Qt::ApplicationModal); key_phase->show(); break; } } } if (slot_btn != NULL && ui->pushButton_alarm->isChecked()) { QString object_name = slot_btn->objectName(); qDebug() << object_name ; Setpoint *setpoint = new Setpoint(); setpoint->setWindowModality(Qt::ApplicationModal); setpoint->show(); } } void MainWindow::on_pushButton_slot_clicked() { if (ui->pushButton_chan->isChecked()) { ui->pushButton_chan->setChecked(false); } if (ui->pushButton_alarm->isChecked()) { ui->pushButton_alarm->setChecked(false); } if (ui->pushButton_point_name->isChecked()) { ui->pushButton_point_name->setChecked(false); } } void MainWindow::on_pushButton_chan_clicked() { if (ui->pushButton_slot->isChecked()) { ui->pushButton_slot->setChecked(false); } if (ui->pushButton_alarm->isChecked()) { ui->pushButton_alarm->setChecked(false); } if (ui->pushButton_point_name->isChecked()) { ui->pushButton_point_name->setChecked(false); } } void MainWindow::on_pushButton_alarm_clicked() { if (ui->pushButton_slot->isChecked()) { ui->pushButton_slot->setChecked(false); } if (ui->pushButton_chan->isChecked()) { ui->pushButton_chan->setChecked(false); } if (ui->pushButton_point_name->isChecked()) { ui->pushButton_point_name->setChecked(false); } } void MainWindow::on_pushButton_point_name_clicked() { if (ui->pushButton_slot->isChecked()) { ui->pushButton_slot->setChecked(false); } if (ui->pushButton_chan->isChecked()) { ui->pushButton_chan->setChecked(false); } if (ui->pushButton_alarm->isChecked()) { ui->pushButton_alarm->setChecked(false); } } void MainWindow::onMenuAction_relay() { qDebug() << " onMenuAction_relay " ; RelaySetting *relay_setting = new RelaySetting(); relay_setting->setWindowModality(Qt::ApplicationModal); relay_setting->show(); } uint8_t calculate_crc(uint8_t c, const QByteArray &data) { uint8_t crc = c; for (int i = 0; i < data.size(); ++i) { crc += static_cast(data[i]); // 累加每个字节 } return crc; } void MainWindow::on_pushButton_save_clicked() { ConfigMgr::Instance()->Save(); // 读取文件内容 QFile file(QCoreApplication::applicationDirPath() + "\\config\\tsi_config_file.json"); if (!file.open(QIODevice::ReadOnly)) { qWarning() << "Failed to open update file."; return; } QByteArray fileData = file.readAll(); int fileSize = fileData.size(); if (fileSize > 10 * 1024 * 1024) { QMessageBox::information(this, QStringLiteral("提示"), "文件大小超过10M,请重新选择!"); file.close(); return; } qDebug() << "fileSize" << fileSize ; // 创建 PackageHead 结构体 PackageHead header = { {0xAA, 0x55, 0xAA}, kUploadConfigFile, fileSize, 0, {} }; // 计算文件的 CRC 校验和 header.crc = calculate_crc(0, fileData); header.len = fileSize; char *send_buf = NULL; send_buf = (char *)malloc(sizeof(PackageHead) + fileData.size() + 1); memset(send_buf, 0, sizeof(PackageHead) + fileData.size() + 1); memcpy(send_buf, &header, sizeof(PackageHead)); memcpy(send_buf + sizeof(PackageHead), fileData.data(), fileData.size()); int length = sizeof(PackageHead) + fileData.size(); const int MAX_CHUNK_SIZE = 50 * 1024; // 50 KB qint64 bytesSent = 0; qint64 totalBytes = length; qDebug() << "totalBytes" << totalBytes ; while (bytesSent < totalBytes) { qint64 chunkSize = 0; if (MAX_CHUNK_SIZE < totalBytes - bytesSent) { chunkSize = MAX_CHUNK_SIZE; } else { chunkSize = totalBytes - bytesSent; } qint64 bytesWritten = m_tcpClient->sendData(send_buf + bytesSent, chunkSize); qDebug() << "bytesWritten" << bytesWritten << "bytesSent" << bytesSent << "chunkSize" << chunkSize ; if (bytesWritten == -1) { break; } bytesSent += bytesWritten; } qDebug() << "bytesSent" << bytesSent; m_tcpClient->waitForRead(); file.close(); if (send_buf != NULL) { free(send_buf); } } void MainWindow::on_pushButton_open_clicked() { ConfigMgr::Instance()->Load(QCoreApplication::applicationDirPath() + "\\config\\tsi_config_file.json"); QList buttonList = btnGroup_slot->buttons(); for (int i = 0; i < buttonList.count(); i++) { std::shared_ptr base_ptr = ConfigMgr::Instance()->GetSlotPtr(i + 1); if(base_ptr != nullptr){ switch (base_ptr->card_type_) { case kCardVibSingle :{ buttonList[i + 1]->setText("振动"); break; } case kCardKeyphaseSingle:{ buttonList[i + 1]->setText("键相"); break; } case kCardSpeedSingle:{ buttonList[i + 1]->setText("转速"); break; } default: break; } } } } uint32_t myHtonl(uint32_t value) { return ((value >> 24) & 0x000000FF) | // 提取最高的8位 ((value >> 8) & 0x0000FF00) | // 提取中间的8位 ((value << 8) & 0x00FF0000) | // 提取次高的8位 ((value << 24) & 0xFF000000); // 提取最低的8位 } void MainWindow::sendUpgradePackage(int slot) { QString filepath = QFileDialog::getOpenFileName(this, tr("选择文件"), tr(""), tr("*")); qDebug() << filepath << slot ; QFileInfo fileinfo; fileinfo = QFileInfo(filepath); QString file_suffix = fileinfo.suffix(); QString FileName = fileinfo.fileName(); if (FileName.isEmpty()) { return; } QFile file(filepath); if (!file.open(QIODevice::ReadOnly)) { qWarning() << "Failed to open update file."; return; } // 读取文件内容 QByteArray fileData = file.readAll(); int fileSize = fileData.size(); if (fileSize > 10 * 1024 * 1024) { QMessageBox::information(this, QStringLiteral("提示"), "文件大小超过10M,请重新选择!"); file.close(); return; } for (int var = 0; var < 10; ++var) { qDebug() << "Byte" << var << ":" << static_cast(fileData[var]); } for (int var = fileSize - 10; var < fileSize; ++var) { qDebug() << "Byte" << var << ":" << static_cast(fileData[var]); } qDebug() << "fileSize" << fileSize ; // 创建 PackageHead 结构体 PackageHead header = { {0xAA, 0x55, 0xAA}, 3, fileSize, 0, {} }; // 计算文件的 CRC 校验和 qDebug() << "filheader.slot" << slot ; UpgradeCardReq upgrade_car_req; if (slot == 0) { upgrade_car_req.card_id = 0xFF; } else { upgrade_car_req.card_id = slot & 0xFF; } header.crc = calculate_crc(upgrade_car_req.card_id, fileData); header.len = fileSize + sizeof(UpgradeCardReq); qDebug() << "filheader.crc" << header.crc << "card_id" << upgrade_car_req.card_id << "header len" << header.len; char *send_buf = NULL; send_buf = (char *)malloc(sizeof(PackageHead) + sizeof(UpgradeCardReq) + fileData.size() + 1); memset(send_buf, 0, sizeof(PackageHead) + sizeof(UpgradeCardReq) + fileData.size() + 1); memcpy(send_buf, &header, sizeof(PackageHead)); memcpy(send_buf + sizeof(PackageHead), &upgrade_car_req, sizeof(UpgradeCardReq)); memcpy(send_buf + sizeof(PackageHead) + sizeof(UpgradeCardReq), fileData.data(), fileData.size()); int length = sizeof(PackageHead) + sizeof(UpgradeCardReq) + fileData.size(); const int MAX_CHUNK_SIZE = 50 * 1024; // 64 KB qint64 bytesSent = 0; qint64 totalBytes = length; qDebug() << "totalBytes" << totalBytes ; while (bytesSent < totalBytes) { qint64 chunkSize = 0; if (MAX_CHUNK_SIZE < totalBytes - bytesSent) { chunkSize = MAX_CHUNK_SIZE; } else { chunkSize = totalBytes - bytesSent; } qint64 bytesWritten = m_tcpClient->sendData(send_buf + bytesSent, chunkSize); qDebug() << "bytesWritten" << bytesWritten << "bytesSent" << bytesSent ; if (bytesWritten == -1) { break; } bytesSent += bytesWritten; } qDebug() << "bytesSent" << bytesSent ; m_tcpClient->waitForRead(); progressBar->reset(); progressBar->setVisible(true); QString upgrade_text = QStringLiteral("正在上传板卡 [ %1 ] …… %p%").arg(slot); progressBar->setTextVisible(true); progressBar->setFormat(upgrade_text); file.close(); if (send_buf != NULL) { free(send_buf); } } void MainWindow::getVersion(int slot) { slot_no = slot; PackageHead header = { {0xAA, 0x55, 0xAA}, kGetVersionInfo, 1, 0, {} }; qDebug() << "slot" << slot ; GetVersionReq get_version_req; if (slot == 0) { get_version_req.card_id = 0xFF; } else { get_version_req.card_id = slot & 0xFF; } char send_buf[20] = {0}; memcpy(send_buf, (char *)&header, sizeof(PackageHead)); memcpy(send_buf + sizeof(PackageHead), (char *)&get_version_req, sizeof(GetVersionReq)); int length = sizeof(PackageHead) + sizeof(GetVersionReq); qint64 bytesWritten = m_tcpClient->sendData(send_buf, length); m_tcpClient->waitForRead(); qDebug() << "bytesWritten: " << bytesWritten; } void MainWindow::readData(const QByteArray &data) { qDebug() << "Received from server:" << data; PackageHead header; memcpy(&header, data.data(), sizeof(PackageHead)); if (header.cmd == kGetVersionInfo) { VersionRsp version_rsp; memcpy(&version_rsp, data.data() + sizeof(PackageHead), sizeof(VersionRsp)); QString strVerion = QString("第 %1 板卡\nFPGA 版本:%2\n软件版本:%3\nFPGA版本日期:%4").arg(slot_no).arg(version_rsp.fpga).arg(version_rsp.sw).arg(version_rsp.fpga_data); QMessageBox::information(this, QStringLiteral("提示"), strVerion); } else if (header.cmd == kUpgradeCard) { UpgradeRsp resp; QByteArray byteArray = data.mid(sizeof(PackageHead)); QDataStream stream(&byteArray, QIODevice::ReadOnly); stream >> resp.code ; // if(resp.code == 1){ // QMessageBox::information(this, QStringLiteral("提示"), "上传成功!"); // } } else if (header.cmd == kUpgradeProgress) { QByteArray byteArray = data.mid(sizeof(PackageHead)); UpgradeRsp upgrade_resp; QDataStream stream(&byteArray, QIODevice::ReadOnly); stream >> upgrade_resp.code ; progressBar->setValue(upgrade_resp.code); if (upgrade_resp.code == 100) { progressBar->setVisible(false); statusBar()->showMessage("升级完成!", 3000); // 显示3秒 } //qDebug() << "Server response: " << upgrade_resp.code; } else if(header.cmd == kDownloadConfigFile){ //qDebug() << "header.len" << header.len; char *config_file = NULL; config_file = (char*)malloc(header.len + 1); memset(config_file,0,header.len + 1); memcpy(config_file, data.data() + sizeof(PackageHead), header.len); QString filename_ = QCoreApplication::applicationDirPath() + "\\config\\tsi_config_file2.json"; //qDebug() << config_file ; QFile file(filename_); file.open(QIODevice::WriteOnly); file.write(config_file,header.len); file.close(); if(config_file != NULL) free(config_file); } } void MainWindow::on_pushButton_download_clicked() { PackageHead header = { {0xAA, 0x55, 0xAA}, kDownloadConfigFile, 1, 0, {} }; char send_buf[20] = {0}; memcpy(send_buf, (char *)&header, sizeof(PackageHead)); int length = sizeof(PackageHead); qint64 bytesWritten = m_tcpClient->sendData(send_buf, length); m_tcpClient->waitForRead(); qDebug() << "bytesWritten: " << bytesWritten; }