#include "mainwindow.h" #include #include #include #include #include #include "../components/loadingWidget.h" #include "../mqtt/mqttclient.h" #include "../serial/serialgpsthread.h" #include "../ui_mainwindow.h" #include "../utils/backendapimanager.h" #include "../utils/global.h" #include "../utils/jobs.h" #include "../utils/logger.h" // 定义 ANzI 转义序列来设置颜色 #define ANSI_COLOR_GREEN "\x1B[32m" #define ANSI_COLOR_RESET "\x1B[0m" #include #include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { try { this->setWindowFlags(Qt::FramelessWindowHint | Qt::Window); this->setWindowState(Qt::WindowMaximized); // Maximizes the window this->setStyleSheet("QWidget { font-size: 16px; }"); this->setStyleSheet("QPushButton { font-size: 16px; }"); ui->setupUi(this); LoadingWidget::init(ui->stackedWidget); initializeAnimate(); initialMqttService(); pageFactories[ui->btnHome] = new HomepageFactory(); pageFactories[ui->btnNew] = new AddressFactory(); pageFactories[ui->btnBlastProject] = new BlastProjectFactory(); pageFactories[ui->btnEquipment] = new EquipmentFactory(); pageFactories[ui->btnDet] = new DetInfoFactory(); pageFactories[ui->btnBlastOper] = new BlastOperationFactory(); pageFactories[ui->btnRecord] = new BlastRecordFactory(); connect(ui->btnToggle, &QPushButton::clicked, this, &MainWindow::onToggleButtonClicked); for (auto *widget : left_button_station) { QPushButton *button = qobject_cast(widget); if (button) { connect(button, &QPushButton::clicked, this, [this, button] { onButtonClicked(button); }); } } initDateTime(); initialBtnSerial(); // initialGPSSerial(); ui->labLat->setText("经度: " + lat); ui->labLon->setText("维度: " + lon); connect(ui->btnClose, &QPushButton::clicked, this, &MainWindow::close); connect(this, &MainWindow::menubarTitleChanged, this, &MainWindow::updateProjectTitleLabel); } catch (const std::exception &ex) { Logger::getInstance().error(QString("Application crashed: %1").arg(ex.what())); QMessageBox::critical(this, "Error", QString("Application crashed: %1").arg(ex.what())); throw; // rethrow to allow further handling if needed } catch (...) { Logger::getInstance().error("Application crashed: Unknown exception"); QMessageBox::critical(this, "Error", "Application crashed: Unknown exception"); throw; } this->switchPage(ui->btnHome); // 默认显示首页 } void MainWindow::updateProjectTitleLabel(const QString &newTitle) { ui->projectTitleLable->setText(newTitle); } void MainWindow::handleRefreshPage() { // 刷新页面 ui->stackedWidget->currentWidget()->update(); } void MainWindow::setMenubarTitle(const QString &newTitle) { if (m_currentProjectTitle != newTitle) { m_currentProjectTitle = newTitle; // Emit the signal to notify listeners (like our QLabel slot) emit menubarTitleChanged(m_currentProjectTitle); } } void MainWindow::initializeAnimate() { move(200, 200); animate_leftFrame = new QPropertyAnimation(ui->leftFrame, "minimumWidth"); animate_leftFrame->setDuration(300); for (QObject *child : ui->left_buttonsBox->children()) { if (qobject_cast(child)) { left_button_station.append(qobject_cast(child)); } } } void MainWindow::onToggleButtonClicked() { // 执行动画 JOBS ::btn_animation(ui->leftFrame, animate_leftFrame); for (QWidget *b : left_button_station) { b->setProperty("spread", !b->property("spread").toBool()); b->setStyleSheet(b->styleSheet()); } } // 选中按钮 void MainWindow::onButtonClicked(QPushButton *button) { setStyleSheets(static_cast(button)); switchPage(static_cast(button)); } void MainWindow::switchPage(QWidget *button) { LoadingWidget::showLoading(this, "请稍等"); if (pageFactories.contains(button)) { PageFactory *factory = pageFactories[button]; if (createdPageByButton.contains(button)) { QWidget *existingPage = createdPageByButton[button]; existingPage->hide(); ui->stackedWidget->removeWidget(existingPage); createdPageByButton.remove(button); } QWidget *newPage = factory->createPage(this); ui->stackedWidget->addWidget(newPage); ui->stackedWidget->setCurrentWidget(newPage); setMenubarTitle(qobject_cast(button)->text()); createdPageByButton.insert(button, newPage); int pageCount = ui->stackedWidget->count(); } LoadingWidget::hideLoading(); } void MainWindow::initialMqttService() { Logger::getInstance().info("Start init Mqtt server."); if (mainMqttClient != nullptr) { QMqttSubscription *projectMsgSubsciber = mainMqttClient->subscribeToTopic(MQTT_TOPIC_COMPANY_PROJECTS_SUB); if (projectMsgSubsciber != nullptr) { connect(projectMsgSubsciber, &QMqttSubscription::messageReceived, this, &MainWindow::handleMqttProjectsMessage); } else { Logger::getInstance().error("Failed to subscribe to MQTT topic: " + MQTT_TOPIC_COMPANY_PROJECTS_SUB); } } else { Logger::getInstance().error("mainMqttClient is null, cannot initialize MQTT service"); } } void MainWindow::publishBlastProjects() { // TODO: publish by emit message // QJsonArray jsonArray; // HProjectDao dao = HProjectDao(DatabaseManager::getInstance().getDatabase()); // QList> projectsReg = dao.getAllHProjectsReg(); // for (const auto &projectPtr : projectsReg) { // if (projectPtr) { // QByteArray projectJson = projectPtr->ProjectToJson(*projectPtr); // QJsonDocument doc = QJsonDocument::fromJson(projectJson); // jsonArray.append(doc.object()); // } // } // QJsonDocument jsonDoc(jsonArray); // QByteArray jsonData = jsonDoc.toJson(QJsonDocument::Indented); // mainMqttClient->sendMessage(MQTT_TOPIC_COMPANY_PROJECTS_PUBLISH, jsonData, 2, true); } void MainWindow::handleMqttProjectsMessage(const QMqttMessage &message) { Logger::getInstance().info("Received Mqtt message on topic: " + message.topic().name() + ", message: " + QString::fromUtf8(message.payload())); QJsonDocument jsonDoc = QJsonDocument::fromJson(message.payload()); if (!jsonDoc.isNull() && jsonDoc.isObject()) { // 注册工程信息 QJsonObject jsonObj = jsonDoc.object(); if (jsonObj.contains("msgType") && jsonObj["msgType"].toString() == "blastSuccess") { // 爆破成功, 更新状态; 尤其是离线爆破的; 服务器收到爆破记录后发布 HProjectDao dao = HProjectDao(DatabaseManager::getInstance().getDatabase()); for (const QJsonValue &projectUuid : jsonObj["projectUuids"].toArray()) { qDebug() << "Received offline project blasted UUID: " << projectUuid; dao.updateBlastStatusByUuid(projectUuid.toString(), BlastStatus::Blasted); } publishBlastProjects(); } } } void MainWindow::setStyleSheets(QPushButton *selectedButton) { for (auto *b : left_button_station) { b->setProperty("selected", b == selectedButton); b->setStyleSheet(b->styleSheet()); // 刷新显示 } } // 处理 MQTT 连接成功的槽函数 void MainWindow::onMqttConnected() { m_isMqttConnected = true; Logger::getInstance().info("Mqtt connected."); } void MainWindow::initialBtnSerial() { bool success; serialTool = SerialTool::getInstance(this, &success); connect(serialTool, &SerialTool::serialPortOpened, this, &MainWindow::onSerialToolCreated); serialTool->setupSerialPort(); Logger::getInstance().info("Fire buttons initialized"); } void MainWindow::onSerialToolCreated() { m_btnSerialInitialized = true; serialTool->releaseInstance(); qDebug() << ANSI_COLOR_GREEN << "Serial tool initialized" << ANSI_COLOR_RESET; Logger::getInstance().info("SerialTool initialized"); } void MainWindow::initialGPSSerial() { Logger::getInstance().info("开始初始化GPS"); SerialGPSThread *threadGPS = new SerialGPSThread(this); connect(threadGPS, &SerialGPSThread::storedGNRMCDataUpdated, this, &MainWindow::handleStoredGNRMCData); threadGPS->start(); } // 槽函数,用于接收 RMCData 数据 void MainWindow::handleStoredGNRMCData(const RMCData &data) { if (data.isValid) { lat = QString::number(data.latitude); lon = QString::number(data.longitude); } else { lat = "定位失败"; lon = "定位失败"; } ui->labLat->setText("经度: " + lat); ui->labLon->setText("纬度: " + lon); labLat = lat; labLon = lon; } void MainWindow::initDateTime() { timeThread = new TimeUpdateThread(this); connect(timeThread, &TimeUpdateThread::timeUpdated, this, &MainWindow::onTimeUpdated); timeThread->start(); } void MainWindow::onTimeUpdated(const QString &timeString) { ui->dateTimeShow->setText(timeString); } MainWindow::~MainWindow() { timeThread->stop(); delete ui; } void MainWindow::mousePressEvent(QMouseEvent *event) { // if (event->button() == Qt::LeftButton) { // m_dragPosition = event->globalPos() - frameGeometry().topLeft(); // event->accept(); // } } void MainWindow::mouseMoveEvent(QMouseEvent *event) { // if (event->buttons() & Qt::LeftButton) { // move(event->globalPos() - m_dragPosition); // event->accept(); // } }