mainwindow.cpp 12 KB

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