DiagnosisPage.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. #include "DiagnosisPage.h"
  2. #include "../common/JQCommon.h"
  3. #include "QPainter"
  4. DiagnosisPage::DiagnosisPage(QWidget *parent)
  5. : QWidget(parent)
  6. {
  7. ui.setupUi(this);
  8. Init();
  9. }
  10. DiagnosisPage::~DiagnosisPage()
  11. {}
  12. void DiagnosisPage::Init()
  13. {
  14. this->setAttribute(Qt::WA_DeleteOnClose);
  15. ui.axisSwitchTabPage->tabBar()->hide();
  16. ui.axisSwitchTabPage->setCurrentIndex(0);
  17. ui.retBut->setIcon(QIcon(":/images/home_openFile.png"));
  18. ui.axisListTree->setHeaderHidden(true);
  19. ui.axisListTree->setEditTriggers(QAbstractItemView::NoEditTriggers);
  20. ns_module::CViewInterface* pCViewInterface = ns_module::CViewInterface::GetInstance();
  21. if (pCViewInterface)
  22. {
  23. m_veCAxis = pCViewInterface->GetViewMotion()->GetAxisList();
  24. // 创建模型
  25. m_model = new QStandardItemModel(this);
  26. QString strModeA;
  27. QStandardItem* pModeType = nullptr;
  28. QStandardItem* rooto = m_model->invisibleRootItem();
  29. QStandardItem* root1 = new QStandardItem(tr("Diagnosis Page", "诊断页面"));
  30. rooto->appendRow(root1);
  31. root1->setFlags(root1->flags() | Qt::ItemIsEnabled);
  32. root1->setCheckState(Qt::Checked);
  33. for (auto a: m_veCAxis)
  34. {
  35. QString strMode = QString::fromLocal8Bit(a->GetModuleType().c_str());
  36. if (strModeA != strMode)
  37. {
  38. pModeType = new QStandardItem(strMode);
  39. pModeType->setCheckState(Qt::Checked);
  40. root1->appendRow(pModeType);
  41. strModeA = strMode;
  42. }
  43. // 添加二级节点
  44. QStandardItem* pAisType = new QStandardItem(QString::fromLocal8Bit(a->GetStringAxisType().c_str()));
  45. pModeType->appendRow(pAisType);
  46. pAisType->setCheckState(Qt::Checked);
  47. }
  48. ui.axisListTree->setModel(m_model);
  49. ui.axisListTree->expandAll();
  50. ui.axisListTree->viewport()->installEventFilter(this);
  51. }
  52. // 控件状态
  53. JQCommon::SetQLineEditLimit(ui.negLineEdit);
  54. JQCommon::SetQLineEditLimit(ui.posLineEdit);
  55. JQCommon::SetQLineEditLimit(ui.speedLineEdit);
  56. }
  57. void DiagnosisPage::SwitchOperationAxisPage(bool isSwitch)
  58. {
  59. if (isSwitch)
  60. {
  61. QString strMode = QString::fromLocal8Bit(m_pCurrOpenCAxis->GetAxisName().c_str());
  62. ui.titleLable->setText(strMode);
  63. // 设置状态
  64. m_IsDriveEnabled = m_pCurrOpenCAxis->JIsDriveEnabled();
  65. ui.xAxisEnabledRadioBut->setChecked(m_IsDriveEnabled);
  66. // 获取正负限位是否打开
  67. bool bEnabledNeg, bEnabledPos;
  68. m_pCurrOpenCAxis->JGetSoftLimitEnableStatus(bEnabledNeg, bEnabledPos);
  69. if (bEnabledNeg && bEnabledPos)
  70. {
  71. double dSoftLimitNeg, dSoftLimitPos, dSoftTravelRange;
  72. m_pCurrOpenCAxis->JGetSoftLimit(dSoftLimitNeg, dSoftLimitPos, dSoftTravelRange);
  73. ui.negLineEdit->setText(QString::number(dSoftLimitNeg,'f',2));
  74. ui.posLineEdit->setText(QString::number(dSoftLimitPos,'f',2));
  75. }
  76. //ui.speedLineEdit->setText(QString::number(0));
  77. // 设置定时获取速度
  78. const int nRunTime = 300; //所有新开的定时器都用这个
  79. m_nTimerID = startTimer(nRunTime);
  80. }
  81. else
  82. {
  83. killTimer(m_nTimerID);
  84. m_nTimerID = 0;
  85. ui.axisSwitchTabPage->setCurrentIndex(0);
  86. }
  87. }
  88. void DiagnosisPage::drawParentChildLine(const QModelIndex& childIndex, QPainter& painter)
  89. {
  90. QModelIndex parentIndex = childIndex.parent();
  91. if (!parentIndex.isValid())
  92. {
  93. // “顶层节点”定义一个固定的起点 (rootX, rootY)
  94. int indent = ui.axisListTree->indentation();
  95. int depth = 0; // 顶层节点深度为0
  96. int branchX = (depth + 1) * indent - indent / 2; // 计算 branchX 基于缩进和深度
  97. // 定义 rootY 为节点中心 Y
  98. QRect childRect = ui.axisListTree->visualRect(childIndex);
  99. if (!childRect.isValid())
  100. return;
  101. int rootY = childRect.center().y();
  102. // 定义横向偏移量
  103. const int hOffset = -20;
  104. // 绘制竖线
  105. painter.drawLine(QPoint(branchX, rootY),
  106. QPoint(branchX, childRect.center().y()));
  107. // 计算新的横线终点
  108. int newX = childRect.left() + hOffset;
  109. // 绘制横线
  110. painter.drawLine(QPoint(branchX, childRect.center().y()),
  111. QPoint(newX, childRect.center().y()));
  112. return;
  113. }
  114. QRect parentRect = ui.axisListTree->visualRect(parentIndex);
  115. QRect childRect = ui.axisListTree->visualRect(childIndex);
  116. if (!parentRect.isValid() || !childRect.isValid()) {
  117. // 父或子超出可视区域
  118. return;
  119. }
  120. int pMidY = parentRect.center().y();
  121. int cMidY = childRect.center().y();
  122. // 计算节点深度
  123. int depth = 0;
  124. QModelIndex p = parentIndex;
  125. while (p.isValid()) {
  126. depth++;
  127. p = p.parent();
  128. }
  129. int indent = ui.axisListTree->indentation();
  130. int branchX = depth * indent - indent / 2;
  131. // branchX 不超出视图范围
  132. branchX = qMax(branchX, 0);
  133. // 定义横向偏移量
  134. const int hOffset = -15;
  135. // 绘制竖线
  136. painter.drawLine(QPoint(branchX, pMidY), QPoint(branchX, cMidY));
  137. // 计算新的横线终点
  138. int newX = childRect.left() + hOffset;
  139. // 绘制横线
  140. painter.drawLine(QPoint(branchX, cMidY), QPoint(newX, cMidY));
  141. }
  142. void DiagnosisPage::drawSiblingLine(const QModelIndex& childIndex, QPainter& painter)
  143. {
  144. QModelIndex parentIndex = childIndex.parent();
  145. if (!parentIndex.isValid())
  146. {
  147. return; // 没有父节点
  148. }
  149. // 下一个兄弟
  150. int row = childIndex.row();
  151. int lastRow = m_model->rowCount(parentIndex) - 1;
  152. if (row >= lastRow)
  153. {
  154. return; // 说明是最后一个兄弟,不用画延伸线
  155. }
  156. QModelIndex nextSibling = m_model->index(row + 1, 0, parentIndex);
  157. QRect currRect = ui.axisListTree->visualRect(childIndex);
  158. QRect nextRect = ui.axisListTree->visualRect(nextSibling);
  159. if (!currRect.isValid() || !nextRect.isValid())
  160. {
  161. return;
  162. }
  163. // 计算节点深度
  164. int depth = 0;
  165. QModelIndex p = parentIndex;
  166. while (p.isValid())
  167. {
  168. depth++;
  169. p = p.parent();
  170. }
  171. int indent = ui.axisListTree->indentation();
  172. int branchX = depth * indent - indent / 2;
  173. // 确保 branchX 不超出视图范围
  174. branchX = qMax(branchX, 0);
  175. // 从当前节点底部向下延伸到下一个兄弟节点顶部
  176. int startY = currRect.bottom();
  177. int endY = nextRect.top();
  178. painter.drawLine(QPoint(branchX, startY), QPoint(branchX, endY));
  179. }
  180. void DiagnosisPage::paintAllBranches(const QModelIndex& parentIndex, QPainter& painter)
  181. {
  182. int rowCount = m_model->rowCount(parentIndex);
  183. for (int i = 0; i < rowCount; ++i)
  184. {
  185. // 当前子节点
  186. QModelIndex childIndex = m_model->index(i, 0, parentIndex);
  187. if (!childIndex.isValid()) continue;
  188. // 1) 父->子拐角线
  189. drawParentChildLine(childIndex, painter);
  190. // 2) 兄弟延续竖线(如果本节点不是最后一个兄弟,就在拐点列画条向下的线)
  191. if (i < rowCount - 1)
  192. {
  193. drawSiblingLine(childIndex, painter);
  194. }
  195. // 3) 递归处理子节点
  196. paintAllBranches(childIndex, painter);
  197. }
  198. }
  199. void DiagnosisPage::uncheckAllItems(const QModelIndex& parent /*= QModelIndex()*/)
  200. {
  201. QAbstractItemModel* model = ui.axisListTree->model();
  202. if (!model) return;
  203. for (int i = 0; i < model->rowCount(parent); ++i) {
  204. QModelIndex child = model->index(i, 0, parent);
  205. // 如果模型支持复选框
  206. if (model->flags(child) & Qt::ItemIsUserCheckable) {
  207. model->setData(child, Qt::Unchecked, Qt::CheckStateRole);
  208. }
  209. // 递归处理子项
  210. if (model->hasChildren(child)) {
  211. uncheckAllItems(child);
  212. }
  213. }
  214. }
  215. void DiagnosisPage::timerEvent(QTimerEvent* event)
  216. {
  217. if (m_nTimerID == event->timerId())
  218. {
  219. if (m_pCurrOpenCAxis)
  220. {
  221. double doPos = 0.0;
  222. m_pCurrOpenCAxis->GetActualPos(doPos);
  223. ui.xPositionLineEdit->setText(QString::number(doPos, 'f', 2));
  224. }
  225. }
  226. }
  227. bool DiagnosisPage::eventFilter(QObject* watched, QEvent* event)
  228. {
  229. if (watched == ui.axisListTree->viewport() && event->type() == QEvent::Paint)
  230. {
  231. // 进行默认绘制
  232. bool handled = QWidget::eventFilter(watched, event);
  233. // 使用 QPainter 叠加画“拐角线”
  234. QPainter painter(ui.axisListTree->viewport());
  235. if (!painter.isActive())
  236. {
  237. //qWarning() << "Painter not active";
  238. return handled;
  239. }
  240. painter.save();
  241. painter.setPen(QPen(Qt::gray, 1, Qt::DashLine)); // 灰色、1px 宽、虚线
  242. // 调用递归函数,绘制所有分支
  243. paintAllBranches(QModelIndex(), painter);
  244. painter.restore();
  245. return handled;
  246. }
  247. // 其余事件交给父类默认处理
  248. return QWidget::eventFilter(watched, event);
  249. }
  250. void DiagnosisPage::on_axisListTree_doubleClicked(const QModelIndex& index)
  251. {
  252. //uncheckAllItems();
  253. if (index.isValid())
  254. {
  255. QString itemName = index.data().toString();
  256. if (!m_model->hasChildren(index)) // 没有子节点
  257. {
  258. // 表示想要切换到轴控制
  259. QModelIndex parentIndex = index.parent();
  260. QString currentItem = parentIndex.data().toString();
  261. currentItem += "_";
  262. currentItem += itemName;
  263. // 给轴窗口
  264. ui.axisSwitchTabPage->setCurrentIndex(1);
  265. for (auto& a : m_veCAxis)
  266. {
  267. QString strMode = QString::fromLocal8Bit(a->GetAxisName().c_str());
  268. if (strMode == currentItem)
  269. {
  270. //m_pCurrOpenCAxis.reset(a);
  271. m_pCurrOpenCAxis = a;
  272. SwitchOperationAxisPage(true);
  273. break;
  274. }
  275. }
  276. }
  277. }
  278. }
  279. void DiagnosisPage::on_xAxisDisable_clicked()
  280. {
  281. QString strText = tr("Disable", "关使能");
  282. if (m_IsDriveEnabled)
  283. {
  284. m_pCurrOpenCAxis->AxisOff();
  285. strText = tr("Enable", "开使能");
  286. }
  287. else
  288. {
  289. m_pCurrOpenCAxis->AxisOn();
  290. }
  291. ui.xAxisDisable->setText(strText);
  292. }
  293. void DiagnosisPage::on_xAxisHomeBut_clicked()
  294. {
  295. m_pCurrOpenCAxis->Home();
  296. }
  297. void DiagnosisPage::on_setPosBut_clicked()
  298. {
  299. double xNeg = ui.negLineEdit->text().toDouble();
  300. double xPos = ui.posLineEdit->text().toDouble();
  301. m_pCurrOpenCAxis->JSetSoftLimit(xNeg, xPos);
  302. }
  303. void DiagnosisPage::on_setNegBut_clicked()
  304. {
  305. double xNeg = ui.negLineEdit->text().toDouble();
  306. double xPos = ui.posLineEdit->text().toDouble();
  307. m_pCurrOpenCAxis->JSetSoftLimit(xNeg, xPos);
  308. }
  309. void DiagnosisPage::on_setSpeedBut_clicked()
  310. {
  311. double doSpeed = ui.speedLineEdit->text().toDouble();
  312. m_pCurrOpenCAxis->JSetTargetVel(doSpeed);
  313. }
  314. void DiagnosisPage::on_retBut_clicked()
  315. {
  316. SwitchOperationAxisPage(false);
  317. }