WindowAppTaskView.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973
  1. #include "WindowAppTaskView.h"
  2. #include "DialogTaskPou.h"
  3. #include "TaskManager.h"
  4. #include "PouManager.h"
  5. #include "WindowAppMdiFrame.h"
  6. #include "DialogTaskOption.h"
  7. #include "WindowAppTaskMonitorView.h"
  8. #include "WindowAppBlockBase.h"
  9. #include "VPGlobal.h"
  10. #include "GvlManager.h"
  11. // 各个列的索引序号
  12. // Pou Table
  13. #define TABLE_POU_INDEX_NAME 0
  14. #define TABLE_POU_INDEX_STATUS 1
  15. #define TABLE_POU_INDEX_EXECTIME 2
  16. #define TABLE_POU_INDEX_EXECCOUNT 3
  17. #define TABLE_POU_INDEX_ERRORCOUNT 4
  18. #define TABLE_POU_COLUMN_COUNT 5
  19. // Tool Table
  20. #define TABLE_TOOL_INDEX_NAME 0
  21. #define TABLE_TOOL_INDEX_STATUS 1
  22. #define TABLE_TOOL_INDEX_RETVALUE 2
  23. #define TABLE_TOOL_INDEX_EXECTIME 3
  24. #define TABLE_TOOL_INDEX_EXECCOUNT 4
  25. #define TABLE_TOOL_INDEX_ERRORCOUNT 5
  26. #define TABLE_TOOL_COLUMN_COUNT 6
  27. WindowAppTaskView::WindowAppTaskView(const QString& strTitle, QWidget* parent)
  28. : QWidget(parent)
  29. , m_strTitle(strTitle)
  30. , m_pTask(nullptr)
  31. {
  32. ui.setupUi(this);
  33. // UI元素初始化
  34. this->initUI();
  35. }
  36. WindowAppTaskView::~WindowAppTaskView()
  37. {
  38. RELEASE(m_pTask);
  39. }
  40. /// <summary>
  41. /// 根据用户选择的初始化参数构建新的任务,并向TaskManager注册
  42. /// </summary>
  43. /// <param name="option"></param>
  44. void WindowAppTaskView::addNewTask(const TASK_OPTION& option)
  45. {
  46. // m_pTask = g_pTaskManager->addNewTask(option,this);
  47. RELEASE(m_pTask);
  48. m_pTask = new TASK(option);
  49. // 向Task Manager注册
  50. g_pTaskManager->registerTask(m_pTask, this);
  51. // 在Task Monitor View中添加Task信息
  52. VPGlobal::getTaskMonitorView()->addNewTask(m_pTask);
  53. this->addTaskVarToSystemGvl(m_pTask);
  54. }
  55. /// <summary>
  56. /// 直接根据Task指针直接生成任务
  57. /// </summary>c
  58. /// <param name="newTask"></param>
  59. void WindowAppTaskView::addNewTask(TASK* newTask)
  60. {
  61. m_pTask = newTask;
  62. g_pTaskManager->registerTask(m_pTask, this);
  63. // 在Task Monitor View中添加Task信息
  64. VPGlobal::getTaskMonitorView()->addNewTask(m_pTask);
  65. this->addTaskVarToSystemGvl(m_pTask);
  66. }
  67. /// <summary>
  68. /// 为Task添加对应的Pou
  69. /// </summary>
  70. /// <param name="selPous"></param>
  71. void WindowAppTaskView::addTaskPous(const QVector<POU*>& selPous)
  72. {
  73. // 首先检查选择的Pou是否有被其他Task选用了的情况
  74. //(每个Pou同一时间只能让一个Task执行)
  75. for (POU* pou : selPous)
  76. {
  77. if (pou->isSelByTask())
  78. {
  79. Utility::VPCriticalMessageBox(pou->pouName() + " is already running in Task[" + pou->m_pParentTask->strName + "]!");
  80. return;
  81. }
  82. }
  83. // 将选择的Pou信息保存到数据结构中
  84. g_pTaskManager->addTaskPous(m_strTitle, selPous);
  85. // 添加对应的Tab界面和Pou表格信息
  86. for (POU* pou : selPous)
  87. {
  88. // 添加新的Tab
  89. this->addNewTab(pou);
  90. int nCount = ui.tablePOU->rowCount();
  91. ui.tablePOU->setRowCount(nCount + 1);
  92. QVector<QTableWidgetItem*> pNewItems;
  93. QTableWidgetItem* newItem = new QTableWidgetItem(pou->pouName());
  94. ui.tablePOU->setItem(nCount, TABLE_POU_INDEX_NAME, newItem);
  95. pNewItems.push_back(newItem);
  96. newItem = new QTableWidgetItem(emExecStatus.key((short)pou->execParams.nStatus));
  97. ui.tablePOU->setItem(nCount, TABLE_POU_INDEX_STATUS, newItem);
  98. pNewItems.push_back(newItem);
  99. newItem = new QTableWidgetItem(QString::number(pou->execParams.nExecTime));
  100. ui.tablePOU->setItem(nCount, TABLE_POU_INDEX_EXECTIME, newItem);
  101. pNewItems.push_back(newItem);
  102. newItem = new QTableWidgetItem(QString::number(pou->execParams.nExecCount));
  103. ui.tablePOU->setItem(nCount, TABLE_POU_INDEX_EXECCOUNT, newItem);
  104. pNewItems.push_back(newItem);
  105. newItem = new QTableWidgetItem(QString::number(pou->execParams.nErrorCount));
  106. ui.tablePOU->setItem(nCount, TABLE_POU_INDEX_ERRORCOUNT, newItem);
  107. pNewItems.push_back(newItem);
  108. for (int i = 0; i < TABLE_POU_COLUMN_COUNT; i++)
  109. {
  110. ui.tablePOU->item(nCount, i)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
  111. }
  112. // 添加两者序号的对应关系
  113. m_RowIndexs.insert(ui.tablePOU->rowCount() - 1, ui.tabPouStatus->count() - 1);
  114. // 保存Pou对应的每一个表格指针,用于更新
  115. m_pouToTableWidgetItems.insert(pou->pouName(), pNewItems);
  116. // 将本Pou和Task绑定
  117. pou->m_pParentTask = m_pTask;
  118. }
  119. // Tab添加完毕后,默认激活第一个
  120. ui.tabPouStatus->setCurrentIndex(0);
  121. }
  122. /// <summary>
  123. /// 为Task中的Pou添加Tool
  124. /// 此时后台的数据结构数据是完整齐全的,只是需要在相关的表格中添加对应的行
  125. /// </summary>
  126. /// <param name="pTask"></param>
  127. /// <param name="pPou"></param>
  128. /// <param name="pTool"></param>
  129. void WindowAppTaskView::addTaskPouTool(const POU* pPou, const TOOL* pTool)
  130. {
  131. // 首先找到对应Pou所在的Table
  132. QTableWidget* pToolTable = m_pouToTables.value(pPou->pouName());
  133. if (pToolTable != nullptr)
  134. {
  135. // Table中增加一行新的工具信息
  136. this->addNewTabTool(pToolTable, pTool);
  137. }
  138. }
  139. /// <summary>
  140. /// 添加 Task 的内部变量到系统全局变量组
  141. /// </summary>
  142. /// <param name="pTask"></param>
  143. void WindowAppTaskView::addTaskVarToSystemGvl(const TASK* pTask)
  144. {
  145. Q_UNUSED(pTask);
  146. //////////////////////////////////////////////////////////////////////////
  147. QString strExecCount = m_pTask->strName + EXEC_COUNT_POSTFIX;
  148. VARIABLE* pNewVariable = new VARIABLE(
  149. GROUP_NAME_SYSTEM,
  150. false,
  151. strExecCount,
  152. "int",
  153. "0",
  154. strExecCount,
  155. g_pGvlManager->getAllGvls()->find(GROUP_NAME_SYSTEM).value()->Variables.size(),
  156. true
  157. );
  158. g_pGvlManager->addNewVariable(GROUP_NAME_SYSTEM, pNewVariable);
  159. VARIABLE* pVar = g_pGvlManager->getVariableByName(GROUP_NAME_SYSTEM, strExecCount);
  160. pVar->value.setValueByAddress((void**)&m_pTask->execParams.nExecCount);
  161. QString strErrorCount = m_pTask->strName + ERROR_COUNT_POSTFIX;
  162. pNewVariable = new VARIABLE(
  163. GROUP_NAME_SYSTEM,
  164. false,
  165. strErrorCount,
  166. "int",
  167. "0",
  168. strErrorCount,
  169. g_pGvlManager->getAllGvls()->find(GROUP_NAME_SYSTEM).value()->Variables.size(),
  170. true
  171. );
  172. g_pGvlManager->addNewVariable(GROUP_NAME_SYSTEM, pNewVariable);
  173. pVar = g_pGvlManager->getVariableByName(GROUP_NAME_SYSTEM, strErrorCount);
  174. pVar->value.setValueByAddress((void**)&m_pTask->execParams.nErrorCount);
  175. }
  176. /// <summary>
  177. /// 从系统全局变量组删除 Task 的内部变量
  178. /// </summary>
  179. /// <param name="pTask"></param>
  180. void WindowAppTaskView::delTaskVar(const TASK* pTask)
  181. {
  182. Q_UNUSED(pTask);
  183. }
  184. /// <summary>
  185. /// 2022-3-5增加,Pou界面中删除了Tool的时候,Task需要同步一下
  186. /// </summary>
  187. /// <param name="strPouName"></param>
  188. /// <param name="strToolName"></param>
  189. void WindowAppTaskView::onDelPouTool(const POU* pPou, const TOOL* pTool)
  190. {
  191. if (!pTool->isIndexedTool())
  192. {
  193. return;
  194. }
  195. // 首先找到对应Pou所在的Table
  196. QTableWidget* pToolTable = m_pouToTables.value(pPou->pouName());
  197. if (pToolTable != nullptr)
  198. {
  199. this->delTabTool(pToolTable, pTool);
  200. m_toolToTableWidgetItems.remove(pTool);
  201. // m_toolToTableRow.remove(pTool);
  202. // qDebug() << "WindowAppTaskView::onDelPouTool - Delete PouTool[" << pTool->strInstanceName << "] from task[" << m_strTitle << "]";
  203. }
  204. }
  205. /// <summary>
  206. /// 2022-3-5增加,Pou界面中调整了Tool顺序的时候,Task需要同步
  207. /// (因为表格中不需要多余的操作,只需要重新全部添加一下即可)
  208. /// </summary>
  209. /// <param name="strPouName"></param>
  210. void WindowAppTaskView::onMovePouTool(const POU* pPou)
  211. {
  212. QTableWidget* pToolTable = m_pouToTables.value(pPou->pouName());
  213. // 清空表格
  214. pToolTable->clearContents();
  215. pToolTable->setRowCount(0);
  216. // 在表格中添加本Pou的Tool信息
  217. const QVector<TOOL*>& allTools = pPou->GetAllStandardTools();
  218. QVectorIterator<TOOL*> i(allTools);
  219. while (i.hasNext())
  220. {
  221. const TOOL* pTool = i.next();
  222. this->addNewTabTool(pToolTable, pTool);
  223. }
  224. }
  225. ///// <summary>
  226. ///// 绑定本视图对应的Task数据结构
  227. ///// </summary>
  228. ///// <param name="newTask"></param>
  229. //void WindowAppTaskView::bindTask(const TASK& newTask)
  230. //{
  231. // m_Task = newTask;
  232. //
  233. // // 将本Task添加进数据结构中
  234. // g_pTaskManager->addTask(&m_Task);
  235. //}
  236. /// <summary>
  237. /// UI元素初始化
  238. /// </summary>
  239. void WindowAppTaskView::initUI()
  240. {
  241. // 初始化Pou表格
  242. this->initPouTable();
  243. // 初始化工具栏
  244. this->initToolBar();
  245. // 初始化Tab页面
  246. this->initTab();
  247. // 设置总体布局
  248. QVBoxLayout* viewLayout = new QVBoxLayout();
  249. viewLayout->addWidget(m_TaskToolbar);
  250. viewLayout->addWidget(ui.tablePOU);
  251. viewLayout->addWidget(ui.labelTool);
  252. viewLayout->addWidget(ui.tabPouStatus);
  253. viewLayout->setContentsMargins(0, 0, 0, 0);
  254. viewLayout->setSpacing(3);
  255. viewLayout->setStretch(1, 1);
  256. viewLayout->setStretch(2, 1);
  257. viewLayout->setStretchFactor(ui.tablePOU, 1);
  258. viewLayout->setStretchFactor(ui.tabPouStatus, 4);
  259. this->setLayout(viewLayout);
  260. connect(this, SIGNAL(sigUpdateTaskStatus()), this, SLOT(updateTaskStatus()));
  261. connect(this, SIGNAL(sigUpdateTaskTable()), this, SLOT(updateTaskTable()));
  262. connect(this, SIGNAL(sigUpdateAllTables(const POU*, const TOOL*)), this, SLOT(updateAllTables(const POU*, const TOOL*)));
  263. connect(this, SIGNAL(sigUpdatePouTable(const POU*)), this, SLOT(updatePouTable(const POU*)));
  264. connect(this, SIGNAL(sigUpdatePouStatus(const POU*)), this, SLOT(updatePouStatus(const POU*)));
  265. connect(this, SIGNAL(sigUpdateToolStatus(const POU*, const TOOL*)), this, SLOT(updateToolStatus(const POU*, const TOOL*)));
  266. }
  267. /// <summary>
  268. /// 初始化Pou表格
  269. /// </summary>
  270. void WindowAppTaskView::initPouTable()
  271. {
  272. // 列数
  273. ui.tablePOU->setColumnCount(TABLE_POU_COLUMN_COUNT);
  274. // 设置表头文字
  275. QStringList headers;
  276. headers
  277. << ("Pou Name")
  278. << ("Execution Status")
  279. << ("Execution Time(ms)")
  280. << ("Execution Count")
  281. << ("Error Count");
  282. ui.tablePOU->setHorizontalHeaderLabels(headers);
  283. // 2021-8-12 增加,此处不设置一个初始化大小的话,首次显示表格的时候会有问题
  284. // ui.tablePOU->horizontalHeader()->setDefaultSectionSize(800);
  285. ui.tablePOU->horizontalHeader()->setStretchLastSection(true);
  286. //设置表头字体
  287. QFont font = ui.tablePOU->horizontalHeader()->font();
  288. font.setBold(true);
  289. ui.tablePOU->horizontalHeader()->setFont(font);
  290. // 设置文字左对齐
  291. ui.tablePOU->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter);
  292. // 设置为不可编辑
  293. ui.tablePOU->setEditTriggers(QAbstractItemView::NoEditTriggers);
  294. // 设置为整行选中模式
  295. ui.tablePOU->setSelectionBehavior(QAbstractItemView::SelectRows);
  296. ui.tablePOU->setSelectionMode(QAbstractItemView::SingleSelection);
  297. // 设置最左侧的序号不用显示
  298. ui.tablePOU->verticalHeader()->setVisible(false);
  299. //设置行高
  300. ui.tablePOU->verticalHeader()->setDefaultSectionSize(10);
  301. //点击表时不对表头行光亮(获取焦点)
  302. ui.tablePOU->horizontalHeader()->setHighlightSections(false);
  303. // 设置表头为红色
  304. //ui.tablePOU->horizontalHeader()->setStyleSheet("QHeaderView::section{background:red;}");
  305. // 绑定双击事件
  306. connect(ui.tablePOU, SIGNAL(cellDoubleClicked(int, int)), this, SLOT(onDoubleClickedTableRow(int, int)));
  307. }
  308. /// <summary>
  309. /// 初始化工具栏
  310. /// </summary>
  311. void WindowAppTaskView::initToolBar()
  312. {
  313. m_TaskToolbar = new QToolBar(this);
  314. m_TaskToolbar->setToolButtonStyle(Qt::ToolButtonIconOnly);
  315. QAction* actionAddPou = new QAction(QIcon(":/image/ZoomOut.png"), ("Add Pou"));
  316. QAction* actionPouUp = new QAction(QIcon(":/image/Up.png"), ("Pou Move Up"));
  317. QAction* actionPouDown = new QAction(QIcon(":/image/Down.png"), ("Pou Move Down"));
  318. QAction* actionDelPou = new QAction(QIcon(":/image/Stop.png"), ("Delete Pou"));
  319. QAction* actionOption = new QAction(QIcon(":/image/Option.png"), ("Options"));
  320. QAction* actionRunOnce = new QAction(QIcon(":/image/RunOnce.png"), ("Run Once"));
  321. m_TaskToolbar->addAction(actionAddPou);
  322. m_TaskToolbar->addAction(actionPouUp);
  323. m_TaskToolbar->addAction(actionPouDown);
  324. m_TaskToolbar->addAction(actionDelPou);
  325. m_TaskToolbar->addSeparator();
  326. m_TaskToolbar->addAction(actionOption);
  327. m_TaskToolbar->addAction(actionRunOnce);
  328. m_TaskToolbar->setIconSize(QSize(16, 16));
  329. // 工具栏的消息响应
  330. connect(actionAddPou, &QAction::triggered, this, &WindowAppTaskView::onAddPou);
  331. connect(actionPouUp, &QAction::triggered, this, &WindowAppTaskView::onMoveUp);
  332. connect(actionPouDown, &QAction::triggered, this, &WindowAppTaskView::onMoveDown);
  333. connect(actionDelPou, &QAction::triggered, this, &WindowAppTaskView::onDelPou);
  334. connect(actionOption, &QAction::triggered, this, &WindowAppTaskView::onOption);
  335. connect(actionRunOnce, &QAction::triggered, this, &WindowAppTaskView::onRunonce);
  336. }
  337. /// <summary>
  338. /// 初始化Tab页面
  339. /// </summary>
  340. void WindowAppTaskView::initTab()
  341. {
  342. // 清空默认的Tab
  343. ui.tabPouStatus->clear();
  344. // 设置不可移动
  345. ui.tabPouStatus->setMovable(false);
  346. // 取消关闭按钮
  347. ui.tabPouStatus->setTabsClosable(false);
  348. }
  349. /// <summary>
  350. /// Add Pou
  351. /// </summary>
  352. void WindowAppTaskView::onAddPou()
  353. {
  354. // 显示变量选择对话框
  355. DialogTaskPou dlgTaskPou;
  356. int res = dlgTaskPou.exec();
  357. if (res != QDialog::Accepted)
  358. {
  359. return;
  360. }
  361. // 获取用户选择的Pou信息
  362. const QVector<POU*> selPous = dlgTaskPou.GetSelectedPous();
  363. // TODO: 此处是否需要在所有Pou选择完毕之后,把Pou中所有Tool的执行参数重置一下
  364. this->addTaskPous(selPous);
  365. }
  366. /// <summary>
  367. /// Delete Pou
  368. /// </summary>
  369. void WindowAppTaskView::onDelPou()
  370. {
  371. // 获取当前选中行
  372. int nSelRow = ui.tablePOU->currentRow();
  373. if (nSelRow < 0)
  374. {
  375. qDebug() << "[Error] WindowAppTaskView::onDelPou - No pou selected.";
  376. return;
  377. }
  378. QString strDelPouName = ui.tablePOU->item(nSelRow, TABLE_POU_INDEX_NAME)->text();
  379. // 2021-8-17 首先判断这个Pou是否在执行,执行中就不要删除了
  380. POU* pDelPou = g_pPouManager->getPouByName(strDelPouName);
  381. if (pDelPou->isRunningInTask())
  382. {
  383. Utility::VPCriticalMessageBox("Can't delete this block : this block is running in task[" + pDelPou->m_pParentTask->strName + "]");
  384. return;
  385. }
  386. // 从数据结构中删除
  387. g_pTaskManager->delTaskPou(m_strTitle, nSelRow);
  388. // 删除对应的Tab
  389. ui.tabPouStatus->removeTab(m_RowIndexs[nSelRow]);
  390. m_TabTables.remove(nSelRow);
  391. m_RowIndexs.remove(nSelRow);
  392. // 删除Pou对应的表格指针
  393. m_pouToTableWidgetItems.remove(strDelPouName);
  394. // 删除Pou对应的Tool表格信息
  395. m_pouToTables.remove(strDelPouName);
  396. // 还需要删除对应的Tool表格指针
  397. QMap<QString, TOOL*> allTools = pDelPou->GetAllTools();
  398. QMapIterator<QString, TOOL*> i(allTools);
  399. while (i.hasNext())
  400. {
  401. const TOOL* pTool = i.next().value();
  402. m_toolToTableWidgetItems.remove(pTool);
  403. }
  404. // 确认无误后,最后从界面中删除Pou的一行
  405. ui.tablePOU->removeRow(nSelRow);
  406. // 清除本Pou的Task信息
  407. pDelPou->m_pParentTask = nullptr;
  408. }
  409. ///// <summary>
  410. ///// Open Pou
  411. ///// </summary>
  412. //void WindowAppTaskView::onOpenPou()
  413. //{
  414. // // 获取当前选中行
  415. // int nSelRow = ui.tablePOU->currentRow();
  416. //
  417. // // 获取PouName
  418. // QString strPou = ui.tablePOU->item(nSelRow, 0)->text();
  419. //
  420. // // 打开对应的Pou页面
  421. // VPGlobal::getMdiFrame()->activeSubView(strPou);
  422. //}
  423. /// <summary>
  424. /// Move up
  425. /// </summary>
  426. void WindowAppTaskView::onMoveUp()
  427. {
  428. // 获取行号
  429. int rowIndex = ui.tablePOU->currentRow();
  430. if (rowIndex <= 0)
  431. {
  432. return;
  433. }
  434. int rowIndex2 = rowIndex - 1;
  435. // 交换两行,以及一系列动作
  436. swapRows(rowIndex, rowIndex2);
  437. }
  438. /// <summary>
  439. /// Move Down
  440. /// </summary>
  441. void WindowAppTaskView::onMoveDown()
  442. {
  443. // 获取行号
  444. int rowIndex = ui.tablePOU->currentRow();
  445. if (rowIndex < 0 || rowIndex == ui.tablePOU->rowCount() - 1)
  446. {
  447. return;
  448. }
  449. int rowIndex2 = rowIndex + 1;
  450. // 交换两行,以及一系列动作
  451. swapRows(rowIndex, rowIndex2);
  452. }
  453. /// <summary>
  454. /// Option
  455. /// </summary>
  456. void WindowAppTaskView::onOption()
  457. {
  458. // 如果任务在运行中,则不允许调整设置
  459. if (m_pTask->isRunning())
  460. {
  461. Utility::VPCriticalMessageBox(" Task [" + m_pTask->strName + "] is running, please stop first!");
  462. return;
  463. }
  464. DialogTaskOption dialogTaskOption(this->m_pTask);
  465. int res = dialogTaskOption.exec();
  466. if (res != QDialog::Accepted)
  467. {
  468. return;
  469. }
  470. // 设置调整完毕之后,需要更新一下Task Manager表格
  471. VPGlobal::getTaskMonitorView()->updateTaskOption(m_pTask);
  472. }
  473. /// <summary>
  474. /// Runonce
  475. /// </summary>
  476. void WindowAppTaskView::onRunonce()
  477. {
  478. // 直接调用Task Manager执行任务
  479. g_pTaskManager->executeTask(m_strTitle, true);
  480. }
  481. /// <summary>
  482. /// 调整大小的消息中改变所有表格的宽度
  483. /// </summary>
  484. /// <param name="event"></param>
  485. void WindowAppTaskView::resizeEvent(QResizeEvent* event)
  486. {
  487. Q_UNUSED(event);
  488. // qDebug() << "WindowAppVariableTable::resizeEvent";
  489. // Pou表格
  490. int nTotalSize = ui.tablePOU->size().width();
  491. if (nTotalSize < 800)
  492. {
  493. nTotalSize = 800;
  494. }
  495. ui.tablePOU->setColumnWidth(TABLE_POU_INDEX_NAME, nTotalSize * 0.30);
  496. ui.tablePOU->setColumnWidth(TABLE_POU_INDEX_STATUS, nTotalSize * 0.17);
  497. ui.tablePOU->setColumnWidth(TABLE_POU_INDEX_EXECTIME, nTotalSize * 0.17);
  498. ui.tablePOU->setColumnWidth(TABLE_POU_INDEX_EXECCOUNT, nTotalSize * 0.17);
  499. ui.tablePOU->setColumnWidth(TABLE_POU_INDEX_ERRORCOUNT, nTotalSize * 0.17);
  500. // 所有的Tool监控表格
  501. for (QTableWidget* pTabTable : m_TabTables)
  502. {
  503. int nTabTableSize = pTabTable->size().width();
  504. pTabTable->setColumnWidth(TABLE_TOOL_INDEX_NAME, nTabTableSize * 0.25);
  505. pTabTable->setColumnWidth(TABLE_TOOL_INDEX_STATUS, nTabTableSize * 0.15);
  506. pTabTable->setColumnWidth(TABLE_TOOL_INDEX_RETVALUE, nTabTableSize * 0.15);
  507. pTabTable->setColumnWidth(TABLE_TOOL_INDEX_EXECTIME, nTabTableSize * 0.15);
  508. pTabTable->setColumnWidth(TABLE_TOOL_INDEX_EXECCOUNT, nTabTableSize * 0.14);
  509. pTabTable->setColumnWidth(TABLE_TOOL_INDEX_ERRORCOUNT, nTabTableSize * 0.14);
  510. }
  511. }
  512. /// <summary>
  513. /// 当双击一行的时候跳转到对应的Pou页面
  514. /// </summary>
  515. /// <param name="nRow"></param>
  516. /// <param name="nCol"></param>
  517. void WindowAppTaskView::onDoubleClickedTableRow(int nRow, int nCol)
  518. {
  519. Q_UNUSED(nCol);
  520. // 获取PouName
  521. QString strPou = ui.tablePOU->item(nRow, 0)->text();
  522. // 打开对应的Pou页面
  523. VPGlobal::getMdiFrame()->activeSubView(strPou);
  524. }
  525. /// <summary>
  526. /// 交换两行的数据
  527. /// </summary>
  528. /// <param name="selectRow"></param>
  529. /// <param name="targetRow"></param>
  530. void WindowAppTaskView::swapRows(int selectRow, int targetRow)
  531. {
  532. // 表格中交换两行
  533. ui.tablePOU->blockSignals(true);
  534. QStringList selectRowLine, targetRowLine;
  535. for (int i = 0; i < TABLE_POU_COLUMN_COUNT; i++)
  536. {
  537. QString strSelect = ui.tablePOU->item(selectRow, i)->text();
  538. QString strTarget = ui.tablePOU->item(targetRow, i)->text();
  539. ui.tablePOU->item(selectRow, i)->setText(strTarget);
  540. ui.tablePOU->item(targetRow, i)->setText(strSelect);
  541. }
  542. this->blockSignals(false);
  543. // 从数据结构中移动
  544. g_pTaskManager->swapTaskPou(m_strTitle, selectRow, targetRow);
  545. // 表格序号移动
  546. qSwap(m_TabTables[selectRow], m_TabTables[targetRow]);
  547. // 调整序号对应关系
  548. int nTmp = m_RowIndexs.value(selectRow);
  549. m_RowIndexs[selectRow] = m_RowIndexs.value(targetRow);
  550. m_RowIndexs[targetRow] = nTmp;
  551. // 需要移动一下焦点
  552. ui.tablePOU->selectRow(targetRow);
  553. }
  554. /// <summary>
  555. /// 添加新的Tool Tab
  556. /// </summary>
  557. /// <param name="strPouName"></param>
  558. void WindowAppTaskView::addNewTab(POU* pPou)
  559. {
  560. // 初始化Tab里的Table
  561. QTableWidget* newTable = this->initToolTable(pPou->pouName());
  562. // 保存此表格和Pou的对应关系
  563. m_pouToTables.insert(pPou->pouName(), newTable);
  564. // 保存此表格到数据结构
  565. m_TabTables.push_back(newTable);
  566. // 将表格嵌入到Tab中
  567. ui.tabPouStatus->addTab(newTable, pPou->pouName());
  568. // 激活此Tab
  569. ui.tabPouStatus->setCurrentIndex(ui.tabPouStatus->count() - 1);
  570. // 设置初始列宽
  571. int nTabTableSize = newTable->size().width();
  572. newTable->setColumnWidth(TABLE_TOOL_INDEX_NAME, nTabTableSize * 0.25);
  573. newTable->setColumnWidth(TABLE_TOOL_INDEX_STATUS, nTabTableSize * 0.15);
  574. newTable->setColumnWidth(TABLE_TOOL_INDEX_RETVALUE, nTabTableSize * 0.15);
  575. newTable->setColumnWidth(TABLE_TOOL_INDEX_EXECTIME, nTabTableSize * 0.15);
  576. newTable->setColumnWidth(TABLE_TOOL_INDEX_EXECCOUNT, nTabTableSize * 0.14);
  577. newTable->setColumnWidth(TABLE_TOOL_INDEX_ERRORCOUNT, nTabTableSize * 0.14);
  578. // 在表格中添加本Pou的Tool信息(按执行顺序)
  579. const QVector<TOOL*>& allTools = pPou->GetAllStandardTools();
  580. QVectorIterator<TOOL*> i(allTools);
  581. while (i.hasNext())
  582. {
  583. const TOOL* pTool = i.next();
  584. this->addNewTabTool(newTable, pTool);
  585. }
  586. }
  587. /// <summary>
  588. /// 添加Tool信息到Tab表格
  589. /// </summary>
  590. /// <param name="pTable"></param>
  591. /// <param name="pTool"></param>
  592. void WindowAppTaskView::addNewTabTool(QTableWidget* pTable, const TOOL* pTool)
  593. {
  594. m_toolToTableWidgetItems.remove(pTool);
  595. // 填充Tool表格,并且保存每一个需要更新的数据表格
  596. QVector<QTableWidgetItem*> pNewItems;
  597. int nCount = pTable->rowCount();
  598. pTable->setRowCount(nCount + 1);
  599. QTableWidgetItem* newItem = new QTableWidgetItem(pTool->strInstanceName);
  600. pTable->setItem(nCount, TABLE_TOOL_INDEX_NAME, newItem);
  601. pNewItems.push_back(newItem);
  602. newItem = new QTableWidgetItem(emExecStatus.key((short)pTool->execParams.nStatus));
  603. pTable->setItem(nCount, TABLE_TOOL_INDEX_STATUS, newItem);
  604. pNewItems.push_back(newItem);
  605. newItem = new QTableWidgetItem(emRetValue.key((short)pTool->execParams.nRetValue));
  606. pTable->setItem(nCount, TABLE_TOOL_INDEX_RETVALUE, newItem);
  607. pNewItems.push_back(newItem);
  608. newItem = new QTableWidgetItem(QString::number(pTool->execParams.nExecTime));
  609. pTable->setItem(nCount, TABLE_TOOL_INDEX_EXECTIME, newItem);
  610. pNewItems.push_back(newItem);
  611. newItem = new QTableWidgetItem(QString::number(pTool->execParams.nExecCount));
  612. pTable->setItem(nCount, TABLE_TOOL_INDEX_EXECCOUNT, newItem);
  613. pNewItems.push_back(newItem);
  614. newItem = new QTableWidgetItem(QString::number(pTool->execParams.nErrorCount));
  615. pTable->setItem(nCount, TABLE_TOOL_INDEX_ERRORCOUNT, newItem);
  616. pNewItems.push_back(newItem);
  617. for (int i = 0; i < TABLE_TOOL_COLUMN_COUNT; i++)
  618. {
  619. pTable->item(nCount, i)->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
  620. }
  621. m_toolToTableWidgetItems.insert(pTool, pNewItems);
  622. }
  623. /// <summary>
  624. /// 删除Tab表格中的Tool信息
  625. /// </summary>
  626. /// <param name="pTable"></param>
  627. /// <param name="pTool"></param>
  628. void WindowAppTaskView::delTabTool(QTableWidget* pTable, const TOOL* pTool)
  629. {
  630. QTableWidgetItem* pToolNameItem = m_toolToTableWidgetItems.value(pTool)[TABLE_TOOL_INDEX_NAME];
  631. int row = pTable->row(pToolNameItem);
  632. pTable->removeRow(row);
  633. }
  634. /// <summary>
  635. /// 初始化Tab里的Table
  636. /// </summary>
  637. QTableWidget* WindowAppTaskView::initToolTable(const QString& strPouName)
  638. {
  639. Q_UNUSED(strPouName);
  640. QTableWidget* newTable = new QTableWidget();
  641. // 列数
  642. newTable->setColumnCount(TABLE_TOOL_COLUMN_COUNT);
  643. // 设置表头文字
  644. QStringList headers;
  645. headers
  646. << ("Tool Name")
  647. << ("Execution Status")
  648. << ("Return Value")
  649. << ("Execution Time(ms)")
  650. << ("Execution Count")
  651. << ("Error Count");
  652. newTable->setHorizontalHeaderLabels(headers);
  653. newTable->horizontalHeader()->setStretchLastSection(true);
  654. //设置表头字体
  655. QFont font = ui.tablePOU->horizontalHeader()->font();
  656. font.setBold(true);
  657. newTable->horizontalHeader()->setFont(font);
  658. // 设置文字左对齐
  659. newTable->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter);
  660. // 设置为不可编辑
  661. newTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
  662. // 设置为整行选中模式
  663. newTable->setSelectionBehavior(QAbstractItemView::SelectRows);
  664. newTable->setSelectionMode(QAbstractItemView::SingleSelection);
  665. // 设置最左侧的序号不用显示
  666. newTable->verticalHeader()->setVisible(false);
  667. //设置行高
  668. newTable->verticalHeader()->setDefaultSectionSize(10);
  669. //点击表时不对表头行光亮(获取焦点)
  670. newTable->horizontalHeader()->setHighlightSections(false);
  671. return newTable;
  672. }
  673. /// <summary>
  674. /// 根据最新的执行结果刷新界面
  675. /// </summary>
  676. void WindowAppTaskView::updateAllTables(const POU* pRunningPou, const TOOL* pRunningTool)
  677. {
  678. // qDebug() << "WindowAppTaskView::updateAllTables";
  679. WindowAppBlockBase* pPortItem = const_cast<POU*>(pRunningPou)->GetToolItem(const_cast<TOOL*>(pRunningTool));
  680. pPortItem->update();
  681. // 刷新Tool表格
  682. this->updateToolTable(pRunningTool);
  683. // 刷新Pou表格
  684. this->updatePouTable(pRunningPou);
  685. // 刷新Task表格中的对应行
  686. this->updateTaskTable();
  687. }
  688. /// <summary>
  689. /// 单独更新Task状态
  690. /// </summary>
  691. void WindowAppTaskView::updateTaskStatus()
  692. {
  693. VPGlobal::getTaskMonitorView()->updateTaskStatus(m_pTask);
  694. }
  695. /// <summary>
  696. /// 单独更新Pou状态
  697. /// </summary>
  698. /// <param name="pRunningPou"></param>
  699. void WindowAppTaskView::updatePouStatus(const POU* pRunningPou)
  700. {
  701. m_pouToTableWidgetItems.value(pRunningPou->pouName())[TABLE_POU_INDEX_STATUS]
  702. ->setText(emExecStatus.key((short)pRunningPou->execParams.nStatus));
  703. }
  704. /// <summary>
  705. /// 单独更新Tool状态
  706. /// </summary>
  707. /// <param name="pRunningTool"></param>
  708. void WindowAppTaskView::updateToolStatus(const POU* pPou, const TOOL* pRunningTool)
  709. {
  710. m_toolToTableWidgetItems.value(pRunningTool)[TABLE_TOOL_INDEX_STATUS]
  711. ->setText(emExecStatus.key((short)pRunningTool->execParams.nStatus));
  712. WindowAppBlockBase* pPortItem = const_cast<POU*>(pPou)->GetToolItem(const_cast<TOOL*>(pRunningTool));
  713. pPortItem->update();
  714. }
  715. /// <summary>
  716. /// 刷新Task表格中的对应行
  717. /// </summary>
  718. void WindowAppTaskView::updateTaskTable()
  719. {
  720. // 调用TaskMonitorView直接更新
  721. VPGlobal::getTaskMonitorView()->updateTask(m_pTask);
  722. }
  723. /// <summary>
  724. /// 刷新Pou表格
  725. /// </summary>
  726. void WindowAppTaskView::updatePouTable(const POU* pRunningPou)
  727. {
  728. if (m_pouToTableWidgetItems.contains(pRunningPou->pouName()))
  729. {
  730. QVector<QTableWidgetItem*>& pItems = m_pouToTableWidgetItems[pRunningPou->pouName()];
  731. const EXEC_PARAMS& params = pRunningPou->execParams;
  732. pItems[TABLE_POU_INDEX_STATUS]->setText(emExecStatus.key((short)params.nStatus));
  733. //pItems[TABLE_POU_INDEX_EXECTIME]->setText(QString::number(params.nExecTime));
  734. if (params.nExecTime != 0)
  735. {
  736. pItems[TABLE_POU_INDEX_EXECTIME]->setText(QString::number(params.nExecTime) + " (" + QString::number(1000.0 / (params.nExecTime + 0.0001), 'f', 1) + "fps)");
  737. }
  738. pItems[TABLE_POU_INDEX_EXECCOUNT]->setText(QString::number(params.nExecCount));
  739. pItems[TABLE_POU_INDEX_ERRORCOUNT]->setText(QString::number(params.nErrorCount));
  740. }
  741. else
  742. {
  743. qDebug() << "[Warning] WindowAppTaskView::updatePouTable - Ingonre, reason: can't find "
  744. << pRunningPou->pouName() << " table.";
  745. }
  746. }
  747. /// <summary>
  748. /// 刷新Tool表格
  749. /// </summary>
  750. void WindowAppTaskView::updateToolTable(const TOOL* pRunningTool)
  751. {
  752. if (m_toolToTableWidgetItems.contains(pRunningTool))
  753. {
  754. // 根据Tool的执行状态更新这个表格对应的数据
  755. QVector<QTableWidgetItem*>& pItems = m_toolToTableWidgetItems[pRunningTool];
  756. const EXEC_PARAMS& params = pRunningTool->execParams;
  757. pItems[TABLE_TOOL_INDEX_STATUS]->setText(emExecStatus.key((short)params.nStatus));
  758. pItems[TABLE_TOOL_INDEX_RETVALUE]->setText(emRetValue.key((short)params.nRetValue));
  759. if (params.nExecTime != 0)
  760. {
  761. pItems[TABLE_TOOL_INDEX_EXECTIME]->setText(QString::number(params.nExecTime) + " (" + QString::number(1000.0 / (params.nExecTime + 0.0001), 'f', 1) + "fps)");
  762. }
  763. pItems[TABLE_TOOL_INDEX_EXECCOUNT]->setText(QString::number(params.nExecCount));
  764. pItems[TABLE_TOOL_INDEX_ERRORCOUNT]->setText(QString::number(params.nErrorCount));
  765. }
  766. else
  767. {
  768. qDebug() << "[Warning] WindowAppTaskView::updatePouTable - Ingonre, reason: can't find " << pRunningTool->strInstanceName << " table.";
  769. }
  770. }