#include "DiagnosisPage.h" #include "../common/JQCommon.h" #include "QPainter" DiagnosisPage::DiagnosisPage(QWidget *parent) : QWidget(parent) { ui.setupUi(this); Init(); } DiagnosisPage::~DiagnosisPage() {} void DiagnosisPage::Init() { this->setAttribute(Qt::WA_DeleteOnClose); ui.axisSwitchTabPage->tabBar()->hide(); ui.axisSwitchTabPage->setCurrentIndex(0); ui.retBut->setIcon(QIcon(":/images/home_openFile.png")); ui.axisListTree->setHeaderHidden(true); ui.axisListTree->setEditTriggers(QAbstractItemView::NoEditTriggers); ns_module::CViewInterface* pCViewInterface = ns_module::CViewInterface::GetInstance(); if (pCViewInterface) { m_veCAxis = pCViewInterface->GetViewMotion()->GetAxisList(); // 创建模型 m_model = new QStandardItemModel(this); QString strModeA; QStandardItem* pModeType = nullptr; QStandardItem* rooto = m_model->invisibleRootItem(); QStandardItem* root1 = new QStandardItem(tr("Diagnosis Page", "诊断页面")); rooto->appendRow(root1); root1->setFlags(root1->flags() | Qt::ItemIsEnabled); root1->setCheckState(Qt::Checked); for (auto a: m_veCAxis) { QString strMode = QString::fromLocal8Bit(a->GetModuleType().c_str()); if (strModeA != strMode) { pModeType = new QStandardItem(strMode); pModeType->setCheckState(Qt::Checked); root1->appendRow(pModeType); strModeA = strMode; } // 添加二级节点 QStandardItem* pAisType = new QStandardItem(QString::fromLocal8Bit(a->GetStringAxisType().c_str())); pModeType->appendRow(pAisType); pAisType->setCheckState(Qt::Checked); } ui.axisListTree->setModel(m_model); ui.axisListTree->expandAll(); ui.axisListTree->viewport()->installEventFilter(this); } // 控件状态 JQCommon::SetQLineEditLimit(ui.negLineEdit); JQCommon::SetQLineEditLimit(ui.posLineEdit); JQCommon::SetQLineEditLimit(ui.speedLineEdit); } void DiagnosisPage::SwitchOperationAxisPage(bool isSwitch) { if (isSwitch) { QString strMode = QString::fromLocal8Bit(m_pCurrOpenCAxis->GetAxisName().c_str()); ui.titleLable->setText(strMode); // 设置状态 m_IsDriveEnabled = m_pCurrOpenCAxis->JIsDriveEnabled(); ui.xAxisEnabledRadioBut->setChecked(m_IsDriveEnabled); // 获取正负限位是否打开 bool bEnabledNeg, bEnabledPos; m_pCurrOpenCAxis->JGetSoftLimitEnableStatus(bEnabledNeg, bEnabledPos); if (bEnabledNeg && bEnabledPos) { double dSoftLimitNeg, dSoftLimitPos, dSoftTravelRange; m_pCurrOpenCAxis->JGetSoftLimit(dSoftLimitNeg, dSoftLimitPos, dSoftTravelRange); ui.negLineEdit->setText(QString::number(dSoftLimitNeg,'f',2)); ui.posLineEdit->setText(QString::number(dSoftLimitPos,'f',2)); } //ui.speedLineEdit->setText(QString::number(0)); // 设置定时获取速度 const int nRunTime = 300; //所有新开的定时器都用这个 m_nTimerID = startTimer(nRunTime); } else { killTimer(m_nTimerID); m_nTimerID = 0; ui.axisSwitchTabPage->setCurrentIndex(0); } } void DiagnosisPage::drawParentChildLine(const QModelIndex& childIndex, QPainter& painter) { QModelIndex parentIndex = childIndex.parent(); if (!parentIndex.isValid()) { // “顶层节点”定义一个固定的起点 (rootX, rootY) int indent = ui.axisListTree->indentation(); int depth = 0; // 顶层节点深度为0 int branchX = (depth + 1) * indent - indent / 2; // 计算 branchX 基于缩进和深度 // 定义 rootY 为节点中心 Y QRect childRect = ui.axisListTree->visualRect(childIndex); if (!childRect.isValid()) return; int rootY = childRect.center().y(); // 定义横向偏移量 const int hOffset = -20; // 绘制竖线 painter.drawLine(QPoint(branchX, rootY), QPoint(branchX, childRect.center().y())); // 计算新的横线终点 int newX = childRect.left() + hOffset; // 绘制横线 painter.drawLine(QPoint(branchX, childRect.center().y()), QPoint(newX, childRect.center().y())); return; } QRect parentRect = ui.axisListTree->visualRect(parentIndex); QRect childRect = ui.axisListTree->visualRect(childIndex); if (!parentRect.isValid() || !childRect.isValid()) { // 父或子超出可视区域 return; } int pMidY = parentRect.center().y(); int cMidY = childRect.center().y(); // 计算节点深度 int depth = 0; QModelIndex p = parentIndex; while (p.isValid()) { depth++; p = p.parent(); } int indent = ui.axisListTree->indentation(); int branchX = depth * indent - indent / 2; // branchX 不超出视图范围 branchX = qMax(branchX, 0); // 定义横向偏移量 const int hOffset = -15; // 绘制竖线 painter.drawLine(QPoint(branchX, pMidY), QPoint(branchX, cMidY)); // 计算新的横线终点 int newX = childRect.left() + hOffset; // 绘制横线 painter.drawLine(QPoint(branchX, cMidY), QPoint(newX, cMidY)); } void DiagnosisPage::drawSiblingLine(const QModelIndex& childIndex, QPainter& painter) { QModelIndex parentIndex = childIndex.parent(); if (!parentIndex.isValid()) { return; // 没有父节点 } // 下一个兄弟 int row = childIndex.row(); int lastRow = m_model->rowCount(parentIndex) - 1; if (row >= lastRow) { return; // 说明是最后一个兄弟,不用画延伸线 } QModelIndex nextSibling = m_model->index(row + 1, 0, parentIndex); QRect currRect = ui.axisListTree->visualRect(childIndex); QRect nextRect = ui.axisListTree->visualRect(nextSibling); if (!currRect.isValid() || !nextRect.isValid()) { return; } // 计算节点深度 int depth = 0; QModelIndex p = parentIndex; while (p.isValid()) { depth++; p = p.parent(); } int indent = ui.axisListTree->indentation(); int branchX = depth * indent - indent / 2; // 确保 branchX 不超出视图范围 branchX = qMax(branchX, 0); // 从当前节点底部向下延伸到下一个兄弟节点顶部 int startY = currRect.bottom(); int endY = nextRect.top(); painter.drawLine(QPoint(branchX, startY), QPoint(branchX, endY)); } void DiagnosisPage::paintAllBranches(const QModelIndex& parentIndex, QPainter& painter) { int rowCount = m_model->rowCount(parentIndex); for (int i = 0; i < rowCount; ++i) { // 当前子节点 QModelIndex childIndex = m_model->index(i, 0, parentIndex); if (!childIndex.isValid()) continue; // 1) 父->子拐角线 drawParentChildLine(childIndex, painter); // 2) 兄弟延续竖线(如果本节点不是最后一个兄弟,就在拐点列画条向下的线) if (i < rowCount - 1) { drawSiblingLine(childIndex, painter); } // 3) 递归处理子节点 paintAllBranches(childIndex, painter); } } void DiagnosisPage::uncheckAllItems(const QModelIndex& parent /*= QModelIndex()*/) { QAbstractItemModel* model = ui.axisListTree->model(); if (!model) return; for (int i = 0; i < model->rowCount(parent); ++i) { QModelIndex child = model->index(i, 0, parent); // 如果模型支持复选框 if (model->flags(child) & Qt::ItemIsUserCheckable) { model->setData(child, Qt::Unchecked, Qt::CheckStateRole); } // 递归处理子项 if (model->hasChildren(child)) { uncheckAllItems(child); } } } void DiagnosisPage::timerEvent(QTimerEvent* event) { if (m_nTimerID == event->timerId()) { if (m_pCurrOpenCAxis) { double doPos = 0.0; m_pCurrOpenCAxis->GetActualPos(doPos); ui.xPositionLineEdit->setText(QString::number(doPos, 'f', 2)); } } } bool DiagnosisPage::eventFilter(QObject* watched, QEvent* event) { if (watched == ui.axisListTree->viewport() && event->type() == QEvent::Paint) { // 进行默认绘制 bool handled = QWidget::eventFilter(watched, event); // 使用 QPainter 叠加画“拐角线” QPainter painter(ui.axisListTree->viewport()); if (!painter.isActive()) { //qWarning() << "Painter not active"; return handled; } painter.save(); painter.setPen(QPen(Qt::gray, 1, Qt::DashLine)); // 灰色、1px 宽、虚线 // 调用递归函数,绘制所有分支 paintAllBranches(QModelIndex(), painter); painter.restore(); return handled; } // 其余事件交给父类默认处理 return QWidget::eventFilter(watched, event); } void DiagnosisPage::on_axisListTree_doubleClicked(const QModelIndex& index) { //uncheckAllItems(); if (index.isValid()) { QString itemName = index.data().toString(); if (!m_model->hasChildren(index)) // 没有子节点 { // 表示想要切换到轴控制 QModelIndex parentIndex = index.parent(); QString currentItem = parentIndex.data().toString(); currentItem += "_"; currentItem += itemName; // 给轴窗口 ui.axisSwitchTabPage->setCurrentIndex(1); for (auto& a : m_veCAxis) { QString strMode = QString::fromLocal8Bit(a->GetAxisName().c_str()); if (strMode == currentItem) { //m_pCurrOpenCAxis.reset(a); m_pCurrOpenCAxis = a; SwitchOperationAxisPage(true); break; } } } } } void DiagnosisPage::on_xAxisDisable_clicked() { QString strText = tr("Disable", "关使能"); if (m_IsDriveEnabled) { m_pCurrOpenCAxis->AxisOff(); strText = tr("Enable", "开使能"); } else { m_pCurrOpenCAxis->AxisOn(); } ui.xAxisDisable->setText(strText); } void DiagnosisPage::on_xAxisHomeBut_clicked() { m_pCurrOpenCAxis->Home(); } void DiagnosisPage::on_setPosBut_clicked() { double xNeg = ui.negLineEdit->text().toDouble(); double xPos = ui.posLineEdit->text().toDouble(); m_pCurrOpenCAxis->JSetSoftLimit(xNeg, xPos); } void DiagnosisPage::on_setNegBut_clicked() { double xNeg = ui.negLineEdit->text().toDouble(); double xPos = ui.posLineEdit->text().toDouble(); m_pCurrOpenCAxis->JSetSoftLimit(xNeg, xPos); } void DiagnosisPage::on_setSpeedBut_clicked() { double doSpeed = ui.speedLineEdit->text().toDouble(); m_pCurrOpenCAxis->JSetTargetVel(doSpeed); } void DiagnosisPage::on_retBut_clicked() { SwitchOperationAxisPage(false); }