WindowAppPouFrame.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  1. #include "WindowAppPouFrame.h"
  2. #include "WindowAppPouScene.h"
  3. #include "DialogNewVariable.h"
  4. #include "GvlManager.h"
  5. #include "PouManager.h"
  6. #include "VPCommand.h"
  7. //template<typename T>
  8. //void SetValue(VALUE& value, T& t)
  9. //{
  10. // value.Ptr = (void**)&t;
  11. //
  12. // qDebug() << "ForTest valueIn: " << *(int*)value.Ptr;
  13. // // For Test
  14. // *(int*)value.Ptr = 40;
  15. // // 此时valueIn的值变为40
  16. // qDebug() << "ForTest valueIn: " << *(int*)value.Ptr;
  17. //}
  18. WindowAppPouFrame::WindowAppPouFrame(const QString& strTitle, QWidget* parent)
  19. : QWidget(parent)
  20. , m_strTitle(strTitle)
  21. , actionUndo(nullptr)
  22. , actionRedo(nullptr)
  23. {
  24. ui.setupUi(this);
  25. // 2022-3-2增加,创建变量表格的同时就顺便创建对应的局部变量组(空)
  26. g_pGvlManager->addNewGroup(m_strTitle, TOOL_TYPE::TOOL_TYPE_LOCAL_VARIABLE, GVL_MODE::GVL_BASIC);
  27. // 初始化图像子界面工具栏
  28. this->initPouToolbar();
  29. // 初始化局部变量子界面工具栏
  30. this->initGvlToolbar();
  31. // 初始化变量表格
  32. ui.tableVariable->initTable(m_strTitle, GVL_MODE::GVL_BASIC);
  33. ui.graphicsView->initView(m_strTitle, this);
  34. // 初始化UI
  35. this->initUI();
  36. // 避免在硬件组态中创建局部变量表和调试页面
  37. if (m_strTitle == GROUP_NAME_HARDWARE)
  38. {
  39. // 隐藏调试页面
  40. ui.pouDebugView->hide();
  41. // 既可以删除Tab
  42. ui.tabWidget->removeTab(0);
  43. // 也可以隐藏Tab
  44. //ui.tabWidget->setTabEnabled(0, false);
  45. //ui.tabWidget->setStyleSheet("QTabBar::tab:disabled {width: 0; color: transparent;}");
  46. // 隐藏工具条
  47. ui.toolbarPouFrame->hide();
  48. }
  49. // 生成鸟瞰图
  50. m_pNavView = new WindowAppPouNavView(this);
  51. m_pNavView->setFixedSize(220, 165);
  52. // 将当前Scene绑定到鸟瞰图中进行同步
  53. m_pNavView->setScene((QGraphicsScene*)ui.graphicsView->getScene());
  54. // 将View也绑定到鸟瞰图中同步
  55. m_pNavView->setMainView(ui.graphicsView);
  56. // 调整VIew
  57. m_pNavView->fitInView(m_pNavView->sceneRect(), Qt::KeepAspectRatio);
  58. // 设置透明度
  59. m_pNavView->setOpacity(0, false);
  60. // 绑定鸟瞰图缩放时的同步刷新动作
  61. connect(ui.graphicsView, &WindowAppPouView::navigatorViewRequired, this, [=](bool required, const QTransform& tf)
  62. {
  63. Q_UNUSED(required);
  64. Q_UNUSED(tf);
  65. //m_pNavView->setTransform(WindowAppPouView::resetScale(tf));
  66. m_pNavView->fitInView(m_pNavView->sceneRect(), Qt::KeepAspectRatio);
  67. m_pNavView->setVisible(required);
  68. m_pNavView->updateMainViewportRegion();
  69. }
  70. );
  71. // 矩形区域变动时的响应动作
  72. connect(ui.graphicsView, &WindowAppPouView::viewportRectChanged, m_pNavView, &WindowAppPouNavView::updateMainViewportRegion);
  73. // 调整分割线
  74. connect(ui.splitter, SIGNAL(splitterMoved(int, int)), this, SLOT(slotSplitterMoved(int, int)));
  75. #ifdef DEBUG_ON_GVL
  76. VARIABLE* pNewVariable = new VARIABLE(
  77. m_strTitle,
  78. true,
  79. "int_lvl_test1", "int", "-30", "Comment1"
  80. );
  81. this->addNewVariable(pNewVariable);
  82. pNewVariable = new VARIABLE(
  83. m_strTitle,
  84. true, "int_lvl_test2", "int", "150", "Comment2"
  85. );
  86. this->addNewVariable(pNewVariable);
  87. pNewVariable = new VARIABLE(
  88. m_strTitle,
  89. true, "int_lvl_test3", "int", "300", "This value is 300."
  90. );
  91. this->addNewVariable(pNewVariable);
  92. pNewVariable = new VARIABLE(
  93. m_strTitle,
  94. false, "double_lvl_test3", "double", "3.1415926", "This is a double variable"
  95. );
  96. this->addNewVariable(pNewVariable);
  97. #endif
  98. }
  99. WindowAppPouFrame::~WindowAppPouFrame()
  100. {
  101. }
  102. /// <summary>
  103. /// UI元素初始化
  104. /// </summary>
  105. void WindowAppPouFrame::initUI()
  106. {
  107. ui.splitter->setOpaqueResize(false);
  108. }
  109. /// <summary>
  110. /// 初始化局部变量子界面工具栏
  111. /// </summary>
  112. void WindowAppPouFrame::initGvlToolbar()
  113. {
  114. m_GvlToolbar = new QToolBar(ui.toolbarVariable);
  115. m_GvlToolbar->setToolButtonStyle(Qt::ToolButtonIconOnly);
  116. m_GvlToolbar->setIconSize(QSize(14, 14));
  117. QAction* actionNew = new QAction(QIcon(":/image/New.png"), ("New"));
  118. QAction* actionMoveUp = new QAction(QIcon(":/image/Up.png"), ("Move up"));
  119. QAction* actionMoveDown = new QAction(QIcon(":/image/Down.png"), ("Move down"));
  120. QAction* actionDel = new QAction(QIcon(":/image/Del.png"), ("Delete"));
  121. m_GvlToolbar->addAction(actionNew);
  122. m_GvlToolbar->addSeparator();
  123. m_GvlToolbar->addAction(actionMoveUp);
  124. m_GvlToolbar->addAction(actionMoveDown);
  125. m_GvlToolbar->addSeparator();
  126. m_GvlToolbar->addAction(actionDel);
  127. // 增加工具栏的消息响应
  128. connect(actionNew, &QAction::triggered, this, &WindowAppPouFrame::onToolGvlNew);
  129. connect(actionMoveUp, &QAction::triggered, this, &WindowAppPouFrame::onToolGvlMoveUp);
  130. connect(actionMoveDown, &QAction::triggered, this, &WindowAppPouFrame::onToolGvlMoveDown);
  131. connect(actionDel, &QAction::triggered, this, &WindowAppPouFrame::onToolGvlDelete);
  132. // 设置为白色背景色
  133. // m_LvlToolbar->setStyleSheet("background-color:rgb(255,255,255)");
  134. }
  135. /// <summary>
  136. /// 初始化图形子界面工具栏
  137. /// </summary>
  138. void WindowAppPouFrame::initPouToolbar()
  139. {
  140. // CAUTION: 这里调试了好久,如果QToolBar的父窗体是QMdiSubWindow的话,这里的工具栏会变成那种弹出式的
  141. // 只有父窗体是View的时候才会是那种正常工具栏
  142. m_PouToolbar = new QToolBar(ui.toolbarPouFrame);
  143. m_PouToolbar->setToolButtonStyle(Qt::ToolButtonIconOnly);
  144. actionMoveUp = new QAction(QIcon(":/image/ZorderTop.png"), ("MoveUp"));
  145. actionMoveDown = new QAction(QIcon(":/image/ZorderBottom.png"), ("MoveDown"));
  146. actionMoveFirst = new QAction(QIcon(":/image/ZorderUp.png"), ("MoveFirst"));
  147. actionMoveLast = new QAction(QIcon(":/image/ZorderDown.png"), ("MoveLast"));
  148. actionAlignLeft = new QAction(QIcon(":/image/AlignLeft.png"), ("Align Left"));
  149. actionAlignTop = new QAction(QIcon(":/image/AlignTop.png"), ("Align Top"));
  150. actionAlignRight = new QAction(QIcon(":/image/AlignRight.png"), ("Align Right"));
  151. actionAlignBottom = new QAction(QIcon(":/image/AlignBottom.png"), ("Align Bottom"));
  152. // 2022-9-29,增加了Undo和Redo按钮
  153. actionUndo = new QAction(QIcon(":/image/Undo.png"), ("Undo"));
  154. actionRedo = new QAction(QIcon(":/image/Redo.png"), ("Redo"));
  155. actionOption = new QAction(QIcon(":/image/Option.png"), ("Options"));
  156. actionRunOnce = new QAction(QIcon(":/image/RunOnce.png"), ("Run Once"));
  157. actionSingleStep = new QAction(QIcon(":/image/RunOnce.png"), ("Single Step"));
  158. m_PouToolbar->addAction(actionMoveUp);
  159. m_PouToolbar->addAction(actionMoveDown);
  160. m_PouToolbar->addAction(actionMoveFirst);
  161. m_PouToolbar->addAction(actionMoveLast);
  162. m_PouToolbar->addSeparator();
  163. m_PouToolbar->addAction(actionAlignLeft);
  164. m_PouToolbar->addAction(actionAlignTop);
  165. m_PouToolbar->addAction(actionAlignRight);
  166. m_PouToolbar->addAction(actionAlignBottom);
  167. m_PouToolbar->addSeparator();
  168. // 2022-9-29,增加了Undo和Redo按钮
  169. m_PouToolbar->addAction(actionUndo);
  170. m_PouToolbar->addAction(actionRedo);
  171. m_PouToolbar->addSeparator();
  172. m_PouToolbar->addAction(actionOption);
  173. m_PouToolbar->addAction(actionRunOnce);
  174. m_PouToolbar->addAction(actionSingleStep);
  175. m_PouToolbar->setIconSize(QSize(14, 14));
  176. connect(actionMoveUp, &QAction::triggered, this, &WindowAppPouFrame::onToolMoveUp);
  177. connect(actionMoveDown, &QAction::triggered, this, &WindowAppPouFrame::onToolMoveDown);
  178. connect(actionMoveFirst, &QAction::triggered, this, &WindowAppPouFrame::onToolMoveFirst);
  179. connect(actionMoveLast, &QAction::triggered, this, &WindowAppPouFrame::onToolMoveLast);
  180. connect(actionAlignLeft, &QAction::triggered, this, &WindowAppPouFrame::onToolAlignLeft);
  181. connect(actionAlignTop, &QAction::triggered, this, &WindowAppPouFrame::onToolAlignTop);
  182. connect(actionAlignRight, &QAction::triggered, this, &WindowAppPouFrame::onToolAlignRight);
  183. connect(actionAlignBottom, &QAction::triggered, this, &WindowAppPouFrame::onToolAlignBottom);
  184. connect(actionUndo, &QAction::triggered, this, &WindowAppPouFrame::onToolUndo);
  185. connect(actionRedo, &QAction::triggered, this, &WindowAppPouFrame::onToolRedo);
  186. connect(actionOption, &QAction::triggered, this, &WindowAppPouFrame::onToolOption);
  187. connect(actionRunOnce, &QAction::triggered, this, &WindowAppPouFrame::onToolRunOnce);
  188. connect(actionSingleStep, &QAction::triggered, this, &WindowAppPouFrame::onToolSingleStep);
  189. }
  190. /// <summary>
  191. /// Toolbar - New
  192. /// </summary>
  193. void WindowAppPouFrame::onToolGvlNew()
  194. {
  195. // qDebug() << "WindowAppGvlView::onToolNew";
  196. // 弹出新增变量对话框
  197. DialogNewVariable dlgNewVar(GVL_MODE::GVL_BASIC, this);
  198. dlgNewVar.setWindowModality(Qt::WindowModal);
  199. dlgNewVar.setGroup(this->m_strTitle);
  200. dlgNewVar.setTagNumber(ui.tableVariable->rowCount());
  201. int res = dlgNewVar.exec();
  202. if (res != QDialog::Accepted)
  203. {
  204. return;
  205. }
  206. // 根据用户输入构造新的变量
  207. VARIABLE* pNewVariable = new VARIABLE(
  208. m_strTitle,
  209. dlgNewVar.m_bSerialized,
  210. dlgNewVar.m_strName,
  211. dlgNewVar.m_strType,
  212. dlgNewVar.m_strValue,
  213. dlgNewVar.m_strComment,
  214. g_pGvlManager->getVariablesCountByGroup(m_strTitle),
  215. true
  216. );
  217. // 在界面和数据结构中添加新的变量
  218. this->addNewVariable(pNewVariable);
  219. // 数据结构中添加本变量信息
  220. g_pGvlManager->addNewVariable(
  221. m_strTitle,
  222. pNewVariable
  223. );
  224. //// 表格中添加一行
  225. //ui.tableVariable->addLocalVariable(
  226. // dlgNewVar.m_bSerialized,
  227. // dlgNewVar.m_strName,
  228. // dlgNewVar.m_strType,
  229. // dlgNewVar.m_strValue,
  230. // dlgNewVar.m_strComment
  231. //);
  232. }
  233. /// <summary>
  234. /// Toolbar - Gvl MoveUp
  235. /// </summary>
  236. void WindowAppPouFrame::onToolGvlMoveUp()
  237. {
  238. ui.tableVariable->onVariableMoveUp();
  239. }
  240. /// <summary>
  241. /// Toolbar - Gvl MoveDown
  242. /// </summary>
  243. void WindowAppPouFrame::onToolGvlMoveDown()
  244. {
  245. ui.tableVariable->onVariableMoveDown();
  246. }
  247. /// <summary>
  248. /// Toolbar - Gvl Delete
  249. /// </summary>
  250. void WindowAppPouFrame::onToolGvlDelete()
  251. {
  252. ui.tableVariable->onVariableDelete();
  253. }
  254. /// <summary>
  255. /// 工具序号 减 1
  256. /// </summary>
  257. void WindowAppPouFrame::onToolMoveUp()
  258. {
  259. ui.graphicsView->getScene()->BlockMoveUp();
  260. }
  261. /// <summary>
  262. /// 工具序号 加 1
  263. /// </summary>
  264. void WindowAppPouFrame::onToolMoveDown()
  265. {
  266. ui.graphicsView->getScene()->BlockMoveDown();
  267. }
  268. /// <summary>
  269. /// 工具序号 置顶
  270. /// </summary>
  271. void WindowAppPouFrame::onToolMoveFirst()
  272. {
  273. ui.graphicsView->getScene()->BlockMoveFirst();
  274. }
  275. /// <summary>
  276. /// 工具序号 置底
  277. /// </summary>
  278. void WindowAppPouFrame::onToolMoveLast()
  279. {
  280. ui.graphicsView->getScene()->BlockMoveLast();
  281. }
  282. /// <summary>
  283. /// 工具左对齐
  284. /// </summary>
  285. void WindowAppPouFrame::onToolAlignLeft()
  286. {
  287. ui.graphicsView->getScene()->BlockAlignLeft();
  288. }
  289. /// <summary>
  290. /// 功能块顶对齐
  291. /// </summary>
  292. void WindowAppPouFrame::onToolAlignTop()
  293. {
  294. ui.graphicsView->getScene()->BlockAlignTop();
  295. }
  296. /// <summary>
  297. /// 功能块右对齐
  298. /// </summary>
  299. void WindowAppPouFrame::onToolAlignRight()
  300. {
  301. ui.graphicsView->getScene()->BlockAlignRight();
  302. }
  303. /// <summary>
  304. /// 功能块底对齐
  305. /// </summary>
  306. void WindowAppPouFrame::onToolAlignBottom()
  307. {
  308. ui.graphicsView->getScene()->BlockAlignBottom();
  309. }
  310. /// <summary>
  311. /// Undo
  312. /// </summary>
  313. void WindowAppPouFrame::onToolUndo()
  314. {
  315. // vDebug() << "WindowAppPouFrame::onToolUndo";
  316. ((WindowAppPouScene*)ui.graphicsView->getScene())->m_CommandManager.undo();
  317. }
  318. /// <summary>
  319. /// Redo
  320. /// </summary>
  321. void WindowAppPouFrame::onToolRedo()
  322. {
  323. // vDebug() << "WindowAppPouFrame::onToolRedo";
  324. ((WindowAppPouScene*)ui.graphicsView->getScene())->m_CommandManager.redo();
  325. }
  326. /// <summary>
  327. /// Option
  328. /// </summary>
  329. void WindowAppPouFrame::onToolOption()
  330. {
  331. vDebug() << "WindowAppPouFrame::onToolOption";
  332. }
  333. /// <summary>
  334. /// 执行一轮
  335. /// </summary>
  336. void WindowAppPouFrame::onToolRunOnce()
  337. {
  338. QFuture<void> Future = QtConcurrent::run(this, &WindowAppPouFrame::ToolRunOnce);
  339. }
  340. /// <summary>
  341. /// 单步执行
  342. /// </summary>
  343. void WindowAppPouFrame::onToolSingleStep()
  344. {
  345. QFuture<void> Future = QtConcurrent::run(this, &WindowAppPouFrame::ToolSingleStep);
  346. }
  347. /// <summary>
  348. /// 线程函数 - 执行一轮
  349. /// </summary>
  350. void WindowAppPouFrame::ToolRunOnce()
  351. {
  352. // 通过名字找到对应的Pou
  353. POU* pou = g_pPouManager->getPouByName(m_strTitle);
  354. // 执行所有工具,执行一轮
  355. pou->ToolExecuteAll();
  356. }
  357. /// <summary>
  358. /// 线程函数 - 单步执行
  359. /// </summary>
  360. void WindowAppPouFrame::ToolSingleStep()
  361. {
  362. // 通过名字找到对应的Pou
  363. POU* pou = g_pPouManager->getPouByName(m_strTitle);
  364. // 单步执行
  365. pou->ToolExecuteSingleStep();
  366. }
  367. /// <summary>
  368. /// 接收键盘消息
  369. /// </summary>
  370. /// <param name="event"></param>
  371. void WindowAppPouFrame::keyPressEvent(QKeyEvent* event)
  372. {
  373. //先检测Ctrl键是否按下
  374. if (QApplication::keyboardModifiers() == Qt::ControlModifier)
  375. {
  376. WindowAppPouScene* pScene = (WindowAppPouScene*)ui.graphicsView->getScene();
  377. if (pScene == nullptr)
  378. {
  379. return;
  380. }
  381. //检测 Z 键,并执行撤销动作
  382. if (event->key() == Qt::Key_Z)
  383. {
  384. if (pScene->m_CommandManager.canUndo())
  385. {
  386. pScene->m_CommandManager.undo();
  387. }
  388. }
  389. // 检测 Y 键,并执行反撤销动作
  390. if (event->key() == Qt::Key_Y)
  391. {
  392. if (pScene->m_CommandManager.canRedo())
  393. {
  394. pScene->m_CommandManager.redo();
  395. }
  396. }
  397. }
  398. }
  399. /// <summary>
  400. /// 在界面中添加新的变量(from序列化文件)
  401. /// </summary>
  402. /// <param name="pNewVariable"></param>
  403. void WindowAppPouFrame::addNewVariable(VARIABLE* pNewVariable)
  404. {
  405. // 2022-2-15增加,Pou内部变量不需要显示在界面中
  406. if (pNewVariable->bShow)
  407. {
  408. // 界面中添加新的一行
  409. ui.tableVariable->insertTableLine(
  410. pNewVariable->bSerialized,
  411. pNewVariable->strName,
  412. pNewVariable->strFullName,
  413. Utility::getTypeString(pNewVariable->value.type),
  414. Utility::getValueString(pNewVariable->value.Ptr, pNewVariable->value.type),
  415. pNewVariable->strComment
  416. );
  417. // 绑定新的变量和界面对应关系,方便变更之后及时发送通知
  418. g_pGvlManager->bindUIAndVariable(ui.tableVariable, pNewVariable->strFullName);
  419. }
  420. }
  421. ///// <summary>
  422. ///// 在界面和数据结构中添加新的TOOL(from序列化文件)
  423. ///// </summary>
  424. ///// <param name="newTool"></param>
  425. //void WindowAppPouFrame::addNewTool(TOOL* pNewTool, QPointF pos)
  426. //{
  427. // ui.graphicsView->addToolDirectly(pNewTool, pos);
  428. //}
  429. ///// <summary>
  430. ///// 在界面中添加新的Link(from序列化文件)
  431. ///// </summary>
  432. ///// <param name="strSrcInf"></param>
  433. ///// <param name="strDstInf"></param>
  434. //void WindowAppPouFrame::addNewLink(const QString& strStartInf, const QString& strEndInf, LINK_MODE linkMode)
  435. //{
  436. // ui.graphicsView->addLinkDirectly(strStartInf, strEndInf, linkMode);
  437. //}
  438. /// <summary>
  439. /// 将功能块的Debug 数据写入UI
  440. /// </summary>
  441. /// <param name="data"></param>
  442. void WindowAppPouFrame::UpdataDebugData(DebugData data)
  443. {
  444. ui.pouDebugView->UpdataDebugData(data);
  445. }
  446. /// <summary>
  447. ///
  448. /// </summary>
  449. /// <param name="event"></param>
  450. void WindowAppPouFrame::resizeEvent(QResizeEvent* event)
  451. {
  452. Q_UNUSED(event);
  453. if (m_pNavView)
  454. {
  455. m_pNavView->move(ui.graphicsView->width() - m_pNavView->width() - 12, ui.graphicsView->height() - m_pNavView->height() + 12);
  456. }
  457. }
  458. /// <summary>
  459. /// 拖动伸缩滑块的时候,调整鸟瞰图窗口位置
  460. /// </summary>
  461. /// <param name=""></param>
  462. /// <param name=""></param>
  463. void WindowAppPouFrame::slotSplitterMoved(int pos, int indext)
  464. {
  465. Q_UNUSED(pos);
  466. Q_UNUSED(indext);
  467. if (m_pNavView)
  468. {
  469. m_pNavView->move(ui.graphicsView->width() - m_pNavView->width() - 12, ui.graphicsView->height() - m_pNavView->height() + 12);
  470. }
  471. }
  472. /// <summary>
  473. /// 鼠标移入的时候,显示鸟瞰图
  474. /// </summary>
  475. /// <param name="event"></param>
  476. void WindowAppPouFrame::enterEvent(QEvent* event)
  477. {
  478. Q_UNUSED(event);
  479. if (m_pNavView)
  480. {
  481. m_pNavView->setOpacity(1);
  482. }
  483. }
  484. /// <summary>
  485. /// 鼠标移出的时候,隐藏鸟瞰图
  486. /// </summary>
  487. /// <param name="event"></param>
  488. void WindowAppPouFrame::leaveEvent(QEvent* event)
  489. {
  490. Q_UNUSED(event);
  491. if (m_pNavView)
  492. {
  493. m_pNavView->setOpacity(0);
  494. }
  495. }
  496. /// <summary>
  497. /// 序列化
  498. /// </summary>
  499. /// <param name="out"></param>
  500. /// <param name="pFrame"></param>
  501. /// <returns></returns>
  502. QDataStream& operator<<(QDataStream& out, const WindowAppPouFrame* pFrame)
  503. {
  504. if (pFrame != nullptr)
  505. {
  506. int paranum;//参数数量
  507. paranum = 2;
  508. out << paranum;//先保存参数数量
  509. out << (int)1 << pFrame->ui.splitter->sizes();
  510. out << (int)2 << pFrame->ui.pouDebugView->getSplitter()->sizes();
  511. }
  512. // Error
  513. else
  514. {
  515. vDebug() << "[Error] WindowAppPouFrame - operator<< failed, pFrame == nullptr";
  516. }
  517. return out;
  518. }
  519. /// <summary>
  520. /// 反序列化
  521. /// </summary>
  522. /// <param name="in"></param>
  523. /// <param name="pFrame"></param>
  524. /// <returns></returns>
  525. QDataStream& operator>>(QDataStream& in, WindowAppPouFrame* pFrame)
  526. {
  527. if (pFrame != nullptr)
  528. {
  529. QList<int> splitters;
  530. QList<int> splittersDdebugView;
  531. int paranum;//参数数量
  532. int para;
  533. in >> paranum;//读取参数数量
  534. for (int i = 0; i < paranum; i++)
  535. {
  536. in >> para;
  537. switch (para)
  538. {
  539. case 1: in >> splitters; break;
  540. case 2: in >> splittersDdebugView; break;
  541. default:
  542. {
  543. vWarning() << "Serialized(In) Error";
  544. }
  545. break;
  546. }
  547. }
  548. // 界面中设置Splitter
  549. pFrame->ui.splitter->setSizes(splitters);
  550. pFrame->ui.pouDebugView->getSplitter()->setSizes(splittersDdebugView);
  551. }
  552. // Error
  553. else
  554. {
  555. vDebug() << "[Error] WindowAppPouFrame - operator>> failed, pFrame == nullptr";
  556. }
  557. return in;
  558. }
  559. /// <summary>
  560. /// 响应Paint事件为了刷新Undo菜单启用禁用(TODO:暂时没有找到更好的位置)
  561. /// </summary>
  562. void WindowAppPouFrame::paintEvent(QPaintEvent* event)
  563. {
  564. Q_UNUSED(event);
  565. // 刷新Undo菜单
  566. this->refreshUndoMenu();
  567. }
  568. /// <summary>
  569. /// 刷新Undo/Redo按钮
  570. /// </summary>
  571. void WindowAppPouFrame::refreshUndoMenu()
  572. {
  573. if (actionUndo != nullptr)
  574. {
  575. WindowAppPouScene* pScene = (WindowAppPouScene*)ui.graphicsView->getScene();
  576. actionUndo->setEnabled(pScene->m_CommandManager.canUndo());
  577. actionRedo->setEnabled(pScene->m_CommandManager.canRedo());
  578. }
  579. }