mainwindow.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. #include "mainwindow.h"
  2. #include <QVBoxLayout>
  3. #include <QDir>
  4. #include <QElapsedTimer>
  5. #include "appcontext.h"
  6. #include "canvas.h"
  7. #include "logger.h"
  8. #include "utils.h"
  9. #include "abstractwidget.h"
  10. #include <QSettings>
  11. #include <QDateTime>
  12. #include <time.h>
  13. MainWindow::MainWindow(const int &frequency, QWidget *parent)
  14. : QMainWindow(parent)
  15. , m_pStackedWidget(nullptr)
  16. , m_pErrStrLabel(nullptr)
  17. , m_frequency(frequency)
  18. {
  19. setWindowFlags(Qt::FramelessWindowHint | Qt::Window);
  20. init_ui();
  21. Network &network = AppContext::instance().network();
  22. connect(&network, &Network::updateScreen, this, &MainWindow::onUpdateScreen);
  23. SerialPort &serialPort = AppContext::instance().serialPort();
  24. connect(&serialPort, &SerialPort::pageSwitch, this, &MainWindow::onPageSwitdh);
  25. HttpServer &httpServer = AppContext::instance().httpServer();
  26. connect(&httpServer, &HttpServer::monitorConfigureUpdate, this, &MainWindow::onConfigureUpdate);
  27. connect(&httpServer, &HttpServer::reloadCanvas, this, &MainWindow::onReloadCanvas);
  28. // DataFifo &dataFifo = AppContext::instance().dataFifo();
  29. // connect(&dataFifo, &DataFifo::updateScreen, this, &MainWindow::onUpdateScreen);
  30. connect(&m_timer, &QTimer::timeout, this, [this](){
  31. DataFifo &dataFifo = AppContext::instance().dataFifo();
  32. qint64 recvTimestamp = dataFifo.recvTimestamp();
  33. qint64 timestamp = QDateTime::currentMSecsSinceEpoch();
  34. if((timestamp - recvTimestamp) >= 5000) {
  35. emit disconnect();
  36. LOG_INFO("data transfer interrupted");
  37. if(!m_pErrStrLabel) {
  38. QFont font;
  39. font.setPixelSize(40);
  40. font.setBold(true);
  41. m_pErrStrLabel = new QLabel("数据传输中断!", this);
  42. m_pErrStrLabel->resize(this->size());
  43. m_pErrStrLabel->setFont(font);
  44. m_pErrStrLabel->setAlignment(Qt::AlignCenter);
  45. m_pErrStrLabel->setStyleSheet("QLabel { background-color: #FFD6D6; color: #D8000C; padding: 4px; border-radius: 4px; }");
  46. m_pErrStrLabel->move((this->width() - m_pErrStrLabel->width()) / 2, (this->height() - m_pErrStrLabel->height()) / 2);
  47. m_pErrStrLabel->show();
  48. }
  49. } else {
  50. if(m_pErrStrLabel) {
  51. delete m_pErrStrLabel;
  52. m_pErrStrLabel = nullptr;
  53. }
  54. }
  55. LOG_INFO("{} {}", timestamp, recvTimestamp);
  56. });
  57. m_timer.start(1000);
  58. connect(&m_updateScreenTimer, &QTimer::timeout, this, &MainWindow::onUpdateScreen);
  59. m_updateScreenTimer.start(1000 / m_frequency);
  60. }
  61. MainWindow::~MainWindow()
  62. {
  63. }
  64. void MainWindow::init_ui()
  65. {
  66. QWidget *pCentralWidget = new QWidget(this);
  67. setCentralWidget(pCentralWidget);
  68. QVBoxLayout *pMainLayout = new QVBoxLayout(pCentralWidget);
  69. m_pStackedWidget = new QStackedWidget(pCentralWidget);
  70. pMainLayout->addWidget(m_pStackedWidget);
  71. pMainLayout->setSpacing(0);
  72. pMainLayout->setContentsMargins(0, 0, 0, 0);
  73. reload();
  74. setCurrentCanvas();
  75. }
  76. void MainWindow::reload()
  77. {
  78. ProjectManager &projectMgr = AppContext::instance().projectManager();
  79. QString fileName = QString("%1/%2").arg(QDir::currentPath(), "conf/monitor.xml");
  80. bool result = projectMgr.openProject(fileName);
  81. if(result) {
  82. LOG_INFO("open monitor config xml success: {}, canvas count: {}", fileName.toUtf8().data(), projectMgr.canvasCount());
  83. } else {
  84. LOG_ERROR("open monitor config xml failed: {}", fileName.toUtf8().data());
  85. return;
  86. }
  87. LOG_INFO("start reload monitor configure");
  88. int canvasCount = projectMgr.canvasCount();
  89. for(int i = 0; i < canvasCount; i++)
  90. {
  91. LOG_DEBUG("----------------canvas {}----------------", i);
  92. Canvas *pCanvas = new Canvas(projectMgr.canvas(i), m_pStackedWidget);
  93. pCanvas->resize(1280, 720);
  94. m_pStackedWidget->insertWidget(i, pCanvas);
  95. }
  96. LOG_INFO("reload monitor configure complete");
  97. }
  98. void MainWindow::clear()
  99. {
  100. LOG_INFO("begin release exist canvas");
  101. {
  102. QList<QWidget*> widgets;
  103. for (int i = 0; i < m_pStackedWidget->count(); ++i) {
  104. widgets << m_pStackedWidget->widget(i);
  105. }
  106. for (QWidget *w : widgets) {
  107. Canvas *pCanvas = static_cast<Canvas *>(w);
  108. pCanvas->clear();
  109. m_pStackedWidget->removeWidget(w);
  110. delete w;
  111. }
  112. }
  113. ProjectManager &projectMgr = AppContext::instance().projectManager();
  114. projectMgr.closeProject();
  115. LOG_INFO("release exist canvas complete, widget count: {}", m_pStackedWidget->count());
  116. }
  117. void MainWindow::setCurrentCanvas(bool isNewComfigure)
  118. {
  119. int index = 0;
  120. if(isNewComfigure) {
  121. int canvasCount = m_pStackedWidget->count();
  122. for(int i = 0; i < canvasCount; i++)
  123. {
  124. QWidget *pWidget = m_pStackedWidget->widget(i);
  125. Canvas *pCanvas = static_cast<Canvas *>(pWidget);
  126. if(pCanvas->isDefault()) {
  127. index = i;
  128. break;
  129. }
  130. }
  131. } else {
  132. QSettings settings("storage/conf/settings.ini", QSettings::IniFormat);
  133. settings.setIniCodec("UTF-8");
  134. settings.beginGroup("CANVAS");
  135. if(settings.contains("INDEX")) {
  136. index = settings.value("INDEX").toInt();
  137. LOG_INFO("find saved canvas index, set index {}", index);
  138. } else {
  139. LOG_INFO("not find saved canvas index, set index 0");
  140. settings.setValue("INDEX", 0);
  141. }
  142. settings.endGroup();
  143. }
  144. m_pStackedWidget->setCurrentIndex(index);
  145. }
  146. void MainWindow::onUpdateScreen()
  147. {
  148. // QElapsedTimer timer;
  149. // timer.start(); // 开始计时
  150. LOG_INFO("update screen");
  151. ProjectManager &projectMgr = AppContext::instance().projectManager();
  152. DataDict &dataDict = AppContext::instance().dataDict();
  153. const QJsonObject obj = dataDict.data();
  154. int canvasCount = projectMgr.canvasCount();
  155. QString timestamp = obj["timestamp"].toString();
  156. LOG_DEBUG("timestamp {}", timestamp.toStdString());
  157. timestamp = QString("%1").arg(timestamp.toULongLong() / 1000000);
  158. QList<QWidget *> widgets;
  159. QList<QStringList> parameters;
  160. for(int i = 0; i < canvasCount; i++)
  161. {
  162. Canvas *pCanvas = static_cast<Canvas *>(m_pStackedWidget->widget(i));
  163. if(!pCanvas) {
  164. LOG_ERROR("error current canvas");
  165. return;
  166. }
  167. widgets = pCanvas->widgetList();
  168. parameters = pCanvas->parameterList();
  169. if(widgets.count() != parameters.count()) {
  170. LOG_ERROR("error widget count and parameters count");
  171. return;
  172. }
  173. int count = widgets.count();
  174. for(int j = 0; j < count; j++)
  175. {
  176. AbstractWidget *pAbstractWidget = static_cast<AbstractWidget *>(widgets[j]);
  177. QStringList widgetParameters;
  178. QMetaObject::invokeMethod(pAbstractWidget, "parameters",
  179. Qt::AutoConnection, Q_RETURN_ARG(QStringList, widgetParameters));
  180. for(auto parameter : widgetParameters)
  181. {
  182. if(obj.contains(parameter)) {
  183. QMetaObject::invokeMethod(
  184. pAbstractWidget,
  185. "setValue",
  186. Qt::AutoConnection,
  187. Q_ARG(QString, parameter),
  188. Q_ARG(QVariant, obj[parameter].toVariant()),
  189. Q_ARG(QString, timestamp));
  190. }
  191. }
  192. if(pCanvas == m_pStackedWidget->currentWidget()) {
  193. QMetaObject::invokeMethod(pAbstractWidget, "redraw", Qt::AutoConnection);
  194. }
  195. }
  196. }
  197. // qint64 duration = timer.elapsed(); // 获取经过的毫秒数
  198. qint64 startTime = obj["time_arrived"].toString().toLongLong();
  199. qint64 endTime = Utils::currentNanoTimestamp();
  200. LOG_INFO("startTime: {}, endTime: {}", startTime, endTime);
  201. LOG_INFO("update screen duration: {}ns", endTime - startTime);
  202. }
  203. void MainWindow::onPageSwitdh(int state)
  204. {
  205. ProjectManager &projectMgr = AppContext::instance().projectManager();
  206. int canvasCount = projectMgr.canvasCount();
  207. if (canvasCount <= 0)
  208. return;
  209. int currentIndex = m_pStackedWidget->currentIndex();
  210. int nextIndex = currentIndex;
  211. if (state < 0) {
  212. // 上一页
  213. nextIndex = (currentIndex - 1 + canvasCount) % canvasCount;
  214. LOG_INFO("page up: {}", nextIndex);
  215. } else if (state > 0) {
  216. // 下一页
  217. nextIndex = (currentIndex + 1) % canvasCount;
  218. LOG_INFO("page down: {}", nextIndex);
  219. } else {
  220. return; // state == 0 不翻页
  221. }
  222. m_pStackedWidget->setCurrentIndex(nextIndex);
  223. QSettings settings("storage/conf/settings.ini", QSettings::IniFormat);
  224. settings.setIniCodec("UTF-8");
  225. settings.beginGroup("CANVAS");
  226. settings.setValue("INDEX", nextIndex);
  227. settings.endGroup();
  228. }
  229. void MainWindow::onConfigureUpdate(const QString &filename)
  230. {
  231. clear();
  232. QString srcFileName = filename;
  233. QString dstFileName = QString("%1/%2").arg(QDir::currentPath(), "conf/monitor.xml");
  234. bool ret;
  235. LOG_INFO("begin delete current monitor configure...");
  236. QFile dstFile = QFile(dstFileName);
  237. if(dstFile.exists())
  238. {
  239. ret = dstFile.remove();
  240. if(ret) {
  241. LOG_INFO("remove current monitor configure successfully");
  242. } else {
  243. LOG_ERROR("remove current monitor configure failed");
  244. return;
  245. }
  246. } else {
  247. QFileInfo fileInfo(dstFileName);
  248. QDir dir = fileInfo.absoluteDir();
  249. if(!dir.exists())
  250. dir.mkpath(dir.path());
  251. }
  252. LOG_INFO("begin copy new monitor configure...");
  253. QFile srcFile = QFile(srcFileName);
  254. if(srcFile.exists()) {
  255. ret = QFile::copy(srcFileName, dstFileName);
  256. if(ret) {
  257. LOG_INFO("update monitor configure successfully");
  258. } else {
  259. LOG_ERROR("update monitor configure failed");
  260. return;
  261. }
  262. } else {
  263. LOG_ERROR("update monitor configure file not exist");
  264. return;
  265. }
  266. reload();
  267. setCurrentCanvas(true);
  268. LOG_INFO("update: default canvas index is {}", m_pStackedWidget->currentIndex());
  269. QSettings settings("storage/conf/settings.ini", QSettings::IniFormat);
  270. settings.setIniCodec("UTF-8");
  271. settings.beginGroup("CANVAS");
  272. settings.setValue("INDEX", m_pStackedWidget->currentIndex());
  273. settings.endGroup();
  274. }
  275. void MainWindow::onReloadCanvas()
  276. {
  277. // reloadCanvas();
  278. clear();
  279. reload();
  280. setCurrentCanvas();
  281. }