mainwindow.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. #include "mainwindow.h"
  2. #include <QtCore/qlist.h>
  3. #include <QtCore/qobject.h>
  4. #include <QDebug>
  5. #include <QPushButton>
  6. #include <QWidget>
  7. #include "backendapimanager.h"
  8. #include "global.h"
  9. #include "jobs.h"
  10. #include "loadingWidget.h"
  11. #include "logger.h"
  12. #include "ui_mainwindow.h"
  13. // 定义 ANzI 转义序列来设置颜色
  14. #define ANSI_COLOR_GREEN "\x1B[32m"
  15. #define ANSI_COLOR_RESET "\x1B[0m"
  16. #include <QMessageBox>
  17. #include <exception>
  18. MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
  19. try {
  20. this->setWindowFlags(Qt::FramelessWindowHint);
  21. this->setWindowState(Qt::WindowMaximized); // Maximizes the window
  22. // this->setFixedSize(1920, 1080);
  23. ui->setupUi(this);
  24. LoadingWidget::init(ui->stackedWidget);
  25. initializeAnimate();
  26. initialMqttService();
  27. pageFactories[ui->btnNew] = new AddressFactory();
  28. pageFactories[ui->btnBlastProject] = new BlastProjectFactory();
  29. pageFactories[ui->btnEquipment] = new EquipmentFactory();
  30. pageFactories[ui->btnDet] = new DetInfoFactory();
  31. pageFactories[ui->btnBlastOper] = new BlastOperationFactory();
  32. pageFactories[ui->btnRecord] = new BlastRecordFactory();
  33. connect(ui->btnToggle, &QPushButton::clicked, this, &MainWindow::onToggleButtonClicked);
  34. for (auto *widget : left_button_station) {
  35. QPushButton *button = qobject_cast<QPushButton *>(widget);
  36. if (button) {
  37. connect(button, &QPushButton::clicked, this,
  38. [this, button] { onButtonClicked(button); });
  39. }
  40. }
  41. initDateTime();
  42. initialBtnSerial();
  43. // initialGPSSerial();
  44. ui->labLat->setText("经度: " + lat);
  45. ui->labLon->setText("维度: " + lon);
  46. connect(ui->btnClose, &QPushButton::clicked, this, &MainWindow::close);
  47. connect(this, &MainWindow::projectTitleChanged, this, &MainWindow::updateProjectTitleLabel);
  48. } catch (const std::exception &ex) {
  49. Logger::getInstance().error(QString("Application crashed: %1").arg(ex.what()));
  50. QMessageBox::critical(this, "Error", QString("Application crashed: %1").arg(ex.what()));
  51. throw; // rethrow to allow further handling if needed
  52. } catch (...) {
  53. Logger::getInstance().error("Application crashed: Unknown exception");
  54. QMessageBox::critical(this, "Error", "Application crashed: Unknown exception");
  55. throw;
  56. }
  57. }
  58. void MainWindow::updateProjectTitleLabel(const QString &newTitle) {
  59. ui->projectTitleLable->setText(newTitle);
  60. }
  61. void MainWindow::setProjectTitle(const QString &newTitle) {
  62. if (m_currentProjectTitle != newTitle) {
  63. m_currentProjectTitle = newTitle;
  64. // Emit the signal to notify listeners (like our QLabel slot)
  65. emit projectTitleChanged(m_currentProjectTitle);
  66. }
  67. }
  68. void MainWindow::initializeAnimate() {
  69. move(200, 200);
  70. animate_leftFrame = new QPropertyAnimation(ui->leftFrame, "minimumWidth");
  71. animate_leftFrame->setDuration(300);
  72. for (QObject *child : ui->left_buttonsBox->children()) {
  73. if (qobject_cast<QWidget *>(child)) {
  74. left_button_station.append(qobject_cast<QWidget *>(child));
  75. }
  76. }
  77. }
  78. void MainWindow::onToggleButtonClicked() {
  79. // 执行动画
  80. JOBS ::btn_animation(ui->leftFrame, animate_leftFrame);
  81. for (QWidget *b : left_button_station) {
  82. b->setProperty("spread", !b->property("spread").toBool());
  83. b->setStyleSheet(b->styleSheet());
  84. }
  85. }
  86. // 选中按钮
  87. void MainWindow::onButtonClicked(QPushButton *button) {
  88. setStyleSheets(static_cast<QPushButton *>(button));
  89. switchPage(static_cast<QPushButton *>(button));
  90. }
  91. void MainWindow::switchPage(QWidget *button) {
  92. LoadingWidget::showLoading(this, "请稍等");
  93. if (pageFactories.contains(button)) {
  94. PageFactory *factory = pageFactories[button];
  95. if (createdPageByButton.contains(button)) {
  96. QWidget *existingPage = createdPageByButton[button];
  97. existingPage->hide();
  98. ui->stackedWidget->removeWidget(existingPage);
  99. createdPageByButton.remove(button);
  100. }
  101. QWidget *newPage = factory->createPage(this);
  102. ui->stackedWidget->addWidget(newPage);
  103. ui->stackedWidget->setCurrentWidget(newPage);
  104. setProjectTitle(qobject_cast<QPushButton *>(button)->text());
  105. createdPageByButton.insert(button, newPage);
  106. int pageCount = ui->stackedWidget->count();
  107. }
  108. LoadingWidget::hideLoading();
  109. }
  110. void MainWindow::initialMqttService() {
  111. Logger::getInstance().info("Start init Mqtt server.");
  112. MqttClient *pcMqttInit = MqttClient::getInstance();
  113. QStringList topics = {"hxgc/topic", "hxgc/companycode/pro/P"};
  114. pcMqttInit->connectToMqttBroker("114.55.233.194", 1883, "hxgc", "hxgc123456", mqttClientId,
  115. topics);
  116. connect(pcMqttInit, &MqttClient::proMessageReceived, this,
  117. &MainWindow::messageAndTopicReceived);
  118. Logger::getInstance().info("Connect Mqtt server request sent.");
  119. }
  120. void MainWindow::messageAndTopicReceived(const QByteArray &message, const QMqttTopicName &topic) {
  121. QJsonDocument jsonDoc = QJsonDocument::fromJson(message);
  122. if (!jsonDoc.isNull() && jsonDoc.isObject()) {
  123. QJsonObject jsonObj = jsonDoc.object();
  124. if (jsonObj.contains("uuid") && jsonObj.contains("status")) {
  125. QJsonValue uuidValue = jsonObj["uuid"];
  126. QJsonValue statusValue = jsonObj["status"];
  127. if (statusValue.isString() && statusValue.toString() == "1") { // "1" 未注册
  128. if (uuidValue.isNull()) {
  129. qDebug() << "uuid 的值为 null";
  130. } else {
  131. QString uuid = uuidValue.toString();
  132. HProjectDao dao = HProjectDao(DatabaseManager::getInstance().getDatabase());
  133. dao.updateBlastStatusByUuid(uuid, "2");
  134. }
  135. }
  136. } else if (jsonObj.contains("msgType") && jsonObj["msgType"].toString() == "safeCheck") {
  137. // 处理安全验证消息
  138. Logger::getInstance().info(QString("收到验证消息接收. message: ").arg(jsonObj));
  139. if (jsonObj["status"] != "ok") {
  140. QMessageBox::warning(this, "安全验证失败",
  141. QString("安全验证未通过,练习安全员确认"));
  142. return;
  143. }
  144. const QString addressUuid = jsonObj["addressUuid"].toString();
  145. QJsonArray addressList = backendAPIManager::getHAddresses();
  146. QList<QString> subAddressUuids = findAllChildUuids(addressList, addressUuid);
  147. HProjectDao dao = HProjectDao(DatabaseManager::getInstance().getDatabase());
  148. QList<QSharedPointer<HProject>> projects =
  149. dao.getPendingSafeCheckProjByAddress(subAddressUuids);
  150. // for (const auto &project : projects) {
  151. // emit firingWidget::safeChecked(project.getUuid());
  152. // }
  153. }
  154. }
  155. }
  156. void MainWindow::setStyleSheets(QPushButton *selectedButton) {
  157. for (auto *b : left_button_station) {
  158. b->setProperty("selected", b == selectedButton);
  159. b->setStyleSheet(b->styleSheet()); // 刷新显示
  160. }
  161. }
  162. // 处理 MQTT 连接成功的槽函数
  163. void MainWindow::onMqttConnected() {
  164. m_isMqttConnected = true;
  165. Logger::getInstance().info("Mqtt connected.");
  166. }
  167. void MainWindow::initialBtnSerial() {
  168. bool success;
  169. serialTool = SerialTool::getInstance(this, &success);
  170. connect(serialTool, &SerialTool::serialPortOpened, this, &MainWindow::onSerialToolCreated);
  171. serialTool->setupSerialPort();
  172. Logger::getInstance().info("Fire buttons initialized");
  173. }
  174. void MainWindow::onSerialToolCreated() {
  175. m_btnSerialInitialized = true;
  176. serialTool->releaseInstance();
  177. qDebug() << ANSI_COLOR_GREEN << "Serial tool initialized" << ANSI_COLOR_RESET;
  178. Logger::getInstance().info("SerialTool initialized");
  179. }
  180. void MainWindow::initialGPSSerial() {
  181. Logger::getInstance().info("开始初始化GPS");
  182. SerialGPSThread *threadGPS = new SerialGPSThread(this);
  183. connect(threadGPS, &SerialGPSThread::storedGNRMCDataUpdated, this,
  184. &MainWindow::handleStoredGNRMCData);
  185. threadGPS->start();
  186. }
  187. // 槽函数,用于接收 RMCData 数据
  188. void MainWindow::handleStoredGNRMCData(const RMCData &data) {
  189. if (data.isValid) {
  190. lat = QString::number(data.latitude);
  191. lon = QString::number(data.longitude);
  192. } else {
  193. lat = "定位失败";
  194. lon = "定位失败";
  195. }
  196. ui->labLat->setText("经度: " + lat);
  197. ui->labLon->setText("纬度: " + lon);
  198. labLat = lat;
  199. labLon = lon;
  200. }
  201. void MainWindow::initDateTime() {
  202. timeThread = new TimeUpdateThread(this);
  203. connect(timeThread, &TimeUpdateThread::timeUpdated, this, &MainWindow::onTimeUpdated);
  204. timeThread->start();
  205. }
  206. void MainWindow::onTimeUpdated(const QString &timeString) { ui->dateTimeShow->setText(timeString); }
  207. MainWindow::~MainWindow() {
  208. timeThread->stop();
  209. delete ui;
  210. }
  211. void MainWindow::mousePressEvent(QMouseEvent *event) {
  212. if (event->button() == Qt::LeftButton) {
  213. m_dragPosition = event->globalPos() - frameGeometry().topLeft();
  214. event->accept();
  215. }
  216. }
  217. void MainWindow::mouseMoveEvent(QMouseEvent *event) {
  218. if (event->buttons() & Qt::LeftButton) {
  219. move(event->globalPos() - m_dragPosition);
  220. event->accept();
  221. }
  222. }
  223. QList<QString> MainWindow::findAllChildUuids(const QJsonArray &addressArray,
  224. const QString targetUuid) {
  225. QList<QString> childrenUuids;
  226. for (const QJsonValue &value : addressArray) {
  227. if (!value.isObject()) continue;
  228. QJsonObject addressObj = value.toObject();
  229. QString currentUuid = addressObj["uuid"].toString();
  230. if (currentUuid == targetUuid) {
  231. // Found the target address, now collect all children UUIDs recursively
  232. if (addressObj.contains("children") && addressObj["children"].isArray()) {
  233. QJsonArray children = addressObj["children"].toArray();
  234. for (const QJsonValue &child : children) {
  235. if (child.isObject()) {
  236. QString childUuid = child.toObject()["uuid"].toString();
  237. childrenUuids.append(childUuid);
  238. // Also add any grandchildren
  239. if (child.toObject().contains("children") &&
  240. child.toObject()["children"].isArray()) {
  241. QJsonArray grandchildren = child.toObject()["children"].toArray();
  242. childrenUuids.append(findAllChildUuids(
  243. grandchildren, child.toObject()["uuid"].toString()));
  244. }
  245. }
  246. }
  247. return childrenUuids;
  248. }
  249. } else if (addressObj.contains("children") && addressObj["children"].isArray()) {
  250. // Continue searching in children
  251. QJsonArray children = addressObj["children"].toArray();
  252. QList<QString> result = findAllChildUuids(children, targetUuid);
  253. if (!result.isEmpty()) {
  254. return result;
  255. }
  256. }
  257. }
  258. return childrenUuids;
  259. }