JonYang 2 weeks ago
parent
commit
165c964041

+ 65 - 44
View/die-bonder-ui/OriginalWnd/DbTreeViewManager.cpp

@@ -271,7 +271,7 @@ void DbTreeViewManager::initializeTree(QString name, const int &userPrivilege)
         CustomizeWndCall(m_pProgrammPage);
 
     }
-    else if (name == "Diagnosis")
+    else if (name == "Diagnosis")  //TODO:yang 推荐后续定制页面都使用我这个
     {
         m_pDiagnosisPage = new DiagnosisPage();
         CustomizeWndCall(m_pDiagnosisPage);
@@ -3064,6 +3064,7 @@ void DbTreeViewManager::onButtonBackClicked()
             }
         }
         // 关闭并销毁字段展示窗口
+        
         m_thirdLevelFieldWnd->close();
         m_thirdLevelFieldWnd->deleteLater();
         m_thirdLevelFieldWnd = nullptr;
@@ -3893,8 +3894,6 @@ void DbTreeViewManager::displayThirdLevelButtons(const QList<CONFIG_BASE_STRUCT>
         m_fieldWidgets.append(textLabel);
         m_fieldWidgets.append(fLabel);
     }
-
-
 }
 
 void DbTreeViewManager::clearThirdLevelMenu()
@@ -3945,7 +3944,8 @@ void DbTreeViewManager::saveCheckedPaths()
 // 加载选中路径
 void DbTreeViewManager::loadCheckedPaths()
 {
-    if (m_currentConfigName == "") {
+    if (m_currentConfigName == "") 
+    {
         //qWarning() << "当前配置ID无效,无法加载复选框状态。";
         return;
     }
@@ -3970,30 +3970,39 @@ void DbTreeViewManager::loadCheckedPaths()
     m_blockItemChanged = false;
 
     // 更新导航栏
-    if (!loadedChecked.isEmpty()) {
+    if (!loadedChecked.isEmpty()) 
+    {
         QString lastPathStr = loadedChecked.last();
         QStringList lastPath = lastPathStr.split("/");
         QModelIndex lastIdx  = findItemByPath(lastPath);
-        if (lastIdx.isValid()) {
+        if (lastIdx.isValid()) 
+        {
             m_pTreeViewDown->setCurrentIndex(lastIdx);
             updateNavigationBar(lastIdx);
         }
-    } else {
+    } 
+    else 
+    {
         // 如果没有加载到任何路径,自动选择第一个目录
         QStandardItem *rootItem = m_pCModel->invisibleRootItem();
-        if (rootItem->rowCount() > 0) {
+        if (rootItem->rowCount() > 0) 
+        {
             QModelIndex firstIndex = m_pCModel->index(0, 0, QModelIndex());
-            if (firstIndex.isValid()) {
+            if (firstIndex.isValid()) 
+            {
                 m_pTreeViewDown->setCurrentIndex(firstIndex);
                 m_pTreeViewDown->expand(firstIndex); // 展开第一个目录
 
                 QStandardItem *firstItem = m_pCModel->itemFromIndex(firstIndex);
                 QVariant data = firstItem->data(Qt::UserRole + 2);
-                if (data.canConvert<QJsonObject>()) {
+                if (data.canConvert<QJsonObject>()) 
+                {
                     QJsonObject thirdLevelObj = data.toJsonObject();
-                    if (thirdLevelObj.contains("IsThirdLevel") && thirdLevelObj["IsThirdLevel"].toBool()) {
+                    if (thirdLevelObj.contains("IsThirdLevel") && thirdLevelObj["IsThirdLevel"].toBool()) 
+                    {
                         QString multiTableName = "";
-                        if (thirdLevelObj.contains("TableName")) {
+                        if (thirdLevelObj.contains("TableName"))
+                        {
                             multiTableName = thirdLevelObj["TableName"].toString();
                         }
                         QList<CONFIG_BASE_STRUCT> buttons;
@@ -4012,7 +4021,8 @@ void DbTreeViewManager::loadCheckedPaths()
 // 保存展开路径
 void DbTreeViewManager::saveExpandedPaths()
 {
-    if (m_currentConfigName == "") {
+    if (m_currentConfigName == "")
+    {
         qWarning() << "当前配置ID无效,无法保存展开路径。";
         return;
     }
@@ -4159,40 +4169,49 @@ DbTreeViewManager::PageState DbTreeViewManager::getCurrentPageState()
     st.directoryId = -1;
 
     // 判断是否在第三层窗口中
-    if (m_thirdLevelFieldWnd && m_thirdLevelFieldWnd->isVisible()) {
+    if (m_thirdLevelFieldWnd && m_thirdLevelFieldWnd->isVisible()) 
+    {
         // 如果此时是在第三层界面,则用当前导航栏 or 目录树的 “选中项” 来获取路径
         QModelIndex curIndex = m_pTreeViewDown->currentIndex();
-        if (!curIndex.isValid()) {
-
+        if (!curIndex.isValid()) 
+        {
             st.path << "未知目录";
-        } else {
+        } 
+        else
+        {
             QStandardItem* item = m_pCModel->itemFromIndex(curIndex);
             st.path = buildItemPath(item);
         }
 
         // 如果能拿到 DirectoryId,则置为第三层
         QVariant dataVar = m_pCModel->itemFromIndex(m_pTreeViewDown->currentIndex())->data(Qt::UserRole + 2);
-        if (dataVar.canConvert<QJsonObject>()) {
+        if (dataVar.canConvert<QJsonObject>())
+        {
             QJsonObject obj = dataVar.toJsonObject();
-            if (obj.contains("IsThirdLevel") && obj["IsThirdLevel"].toBool()) {
+            if (obj.contains("IsThirdLevel") && obj["IsThirdLevel"].toBool()) 
+            {
                 st.isThirdLevel = true;
                 st.directoryId = obj.value("Id").toInt(-1);
                 st.multiTableName = obj.value("TableName").toString();
             }
         }
     }
-    else {
+    else
+    {
         // 当前是目录树界面,就看 treeView 选中项
         QModelIndex curIndex = m_pTreeViewDown->currentIndex();
-        if (curIndex.isValid()) {
+        if (curIndex.isValid())
+        {
             QStandardItem* item = m_pCModel->itemFromIndex(curIndex);
             st.path = buildItemPath(item);
 
             // 检查是否第三层
             QVariant dataVar = item->data(Qt::UserRole + 2);
-            if (dataVar.canConvert<QJsonObject>()) {
+            if (dataVar.canConvert<QJsonObject>())
+            {
                 QJsonObject obj = dataVar.toJsonObject();
-                if (obj.contains("IsThirdLevel") && obj["IsThirdLevel"].toBool()) {
+                if (obj.contains("IsThirdLevel") && obj["IsThirdLevel"].toBool())
+                {
                     st.isThirdLevel = true;
                     st.directoryId = obj.value("Id").toInt(-1);
                     st.multiTableName = obj.value("TableName").toString();
@@ -4210,7 +4229,8 @@ void DbTreeViewManager::loadPageState(const PageState &st, bool isByHistoryNav)
 {
     // 先根据 st.path 找到对应的节点
     QModelIndex idx = findItemByPath(st.path);
-    if (!idx.isValid()) {
+    if (!idx.isValid()) 
+    {
         qWarning() << "[loadPageState] 未找到路径" << st.path;
         return;
     }
@@ -4222,15 +4242,11 @@ void DbTreeViewManager::loadPageState(const PageState &st, bool isByHistoryNav)
     // 更新导航栏
     updateNavigationBar(idx);
 
-    // 如果是第三层,就加载对应的数据窗口
-    if (st.isThirdLevel && st.directoryId != -1) {
-        // 如果当前已在一个第三层窗口,先关闭它
-        if (m_thirdLevelFieldWnd) {
-            m_thirdLevelFieldWnd->close();
-            m_thirdLevelFieldWnd->deleteLater();
-            m_thirdLevelFieldWnd = nullptr;
-        }
+    DelMemoryWnd(m_thirdLevelFieldWnd);
 
+    // 如果是第三层,就加载对应的数据窗口
+    if (st.isThirdLevel && st.directoryId != -1) 
+    {
         int userPrivilege = 0x1;
         QList<ST_TABLE_CONTROL_DATA> tableControlDatas;
         bool allChangeFlag = false;
@@ -4238,25 +4254,28 @@ void DbTreeViewManager::loadPageState(const PageState &st, bool isByHistoryNav)
         displayThirdLevelFields(tableControlDatas, allChangeFlag, false);   // 传递参数表示 Home 界面
         //QJsonObject data = fetchThirdLevelData(st.directoryId, userPrivilege);
         //displayThirdLevelFields(data, (m_currentConfigName == "Home"));
-    } else {
+    } 
+    else
+    {
         // 否则,显示目录树
-        if (m_thirdLevelFieldWnd) {
-            m_thirdLevelFieldWnd->close();
-            m_thirdLevelFieldWnd->deleteLater();
-            m_thirdLevelFieldWnd = nullptr;
-        }
         m_pTreeViewDown->show();
-        for (auto sep : m_mapFirstLevelSeparators) {
-            if (sep) sep->show();
+        for (auto sep : m_mapFirstLevelSeparators) 
+        {
+            if (sep)
+            {
+                sep->show();
+            }
         }
     }
 
-    if (!isByHistoryNav) {
+    if (!isByHistoryNav) 
+    {
         m_forwardStack.clear();
         buttonRight->setIcon(QIcon(":/images/home_right.png"));
         //   把新状态压入后退栈
         m_backStack.append(st);
-        if(m_backStack.size() >= 2){
+        if(m_backStack.size() >= 2)
+        {
             buttonLeft->setIcon(QIcon(":/images/home_left.png"));
         }
     }
@@ -4270,10 +4289,12 @@ void DbTreeViewManager::loginput(const QString& fieldTableName, const QString& f
     writeLogToFile(logMessage,pathoflog);
 }
 
-void DbTreeViewManager::writeLogToFile(const QString& logMessage, const QString& filePath) {
+void DbTreeViewManager::writeLogToFile(const QString& logMessage, const QString& filePath) 
+{
     QFile logFile(filePath);
 
-    if (!logFile.open(QIODevice::Append | QIODevice::Text)) {
+    if (!logFile.open(QIODevice::Append | QIODevice::Text))
+    {
         qWarning() << "Cannot open file for writing:" << filePath;
         return;
     }

+ 1 - 0
View/die-bonder-ui/OriginalWnd/DbTreeViewManager.h

@@ -157,6 +157,7 @@ private:
     /**释放内存窗口
      */
     void DelMemoryWnd(QWidget* pWid);
+
 private:
     /** 编程界面
     */

+ 195 - 2
View/die-bonder-ui/Src/DiagnosisPage/DiagnosisPage.cpp

@@ -1,5 +1,6 @@
 #include "DiagnosisPage.h"
 #include "../common/JQCommon.h"
+#include "QPainter"
 
 DiagnosisPage::DiagnosisPage(QWidget *parent)
     : QWidget(parent)
@@ -17,6 +18,9 @@ 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);
 
@@ -33,6 +37,7 @@ void DiagnosisPage::Init()
         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)
         {
@@ -40,7 +45,7 @@ void DiagnosisPage::Init()
             if (strModeA != strMode)
             {
                 pModeType = new QStandardItem(strMode);
-                
+                pModeType->setCheckState(Qt::Checked);
                 root1->appendRow(pModeType);
                 strModeA = strMode;
             }
@@ -48,11 +53,12 @@ void DiagnosisPage::Init()
             // 添加二级节点
             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);
     }
     
     // 控件状态
@@ -98,6 +104,165 @@ void DiagnosisPage::SwitchOperationAxisPage(bool isSwitch)
     }
 }
 
+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())
@@ -111,8 +276,36 @@ void DiagnosisPage::timerEvent(QTimerEvent* event)
     }
 }
 
+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();

+ 19 - 0
View/die-bonder-ui/Src/DiagnosisPage/DiagnosisPage.h

@@ -32,8 +32,27 @@ private:
      */
     void SwitchOperationAxisPage(bool isSwitch);
 
+    /**
+    * @brief 绘制父节点到子节点的“拐角线”
+    * @param childIndex  子节点索引
+    * @param painter     QPainter 引用
+    */
+    void drawParentChildLine(const QModelIndex& childIndex, QPainter& painter);
+
+    /**
+     * @brief 兄弟节点之间的竖线连接
+     * @param childIndex  当前节点索引
+     * @param painter     QPainter 引用
+     */
+    void drawSiblingLine(const QModelIndex& childIndex, QPainter& painter);
+    void paintAllBranches(const QModelIndex& parentIndex, QPainter& painter);
+
+    void uncheckAllItems(const QModelIndex& parent = QModelIndex());
+private:
     void timerEvent(QTimerEvent* event) override; 
 
+    bool eventFilter(QObject* watched, QEvent* event) override;
+
 private slots:
     void on_axisListTree_doubleClicked(const QModelIndex& index);
 

+ 24 - 5
View/die-bonder-ui/Src/DiagnosisPage/DiagnosisPage.ui

@@ -26,7 +26,7 @@
     </rect>
    </property>
    <property name="currentIndex">
-    <number>1</number>
+    <number>0</number>
    </property>
    <widget class="QWidget" name="AxisTab">
     <attribute name="title">
@@ -206,7 +206,7 @@
        </item>
       </layout>
      </widget>
-     <widget class="QWidget" name="">
+     <widget class="QWidget" name="layoutWidget">
       <property name="geometry">
        <rect>
         <x>10</x>
@@ -280,7 +280,7 @@
        </item>
       </layout>
      </widget>
-     <widget class="QWidget" name="">
+     <widget class="QWidget" name="layoutWidget">
       <property name="geometry">
        <rect>
         <x>10</x>
@@ -370,10 +370,29 @@
     </rect>
    </property>
    <property name="styleSheet">
-    <string notr="true">background-color: rgb(203,208,255);</string>
+    <string notr="true"/>
    </property>
    <property name="text">
-    <string extracomment="返回选择所有轴">Ret All Axis</string>
+    <string extracomment="返回选择所有轴"/>
+   </property>
+  </widget>
+  <widget class="QFrame" name="frame">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>70</y>
+     <width>481</width>
+     <height>2</height>
+    </rect>
+   </property>
+   <property name="styleSheet">
+    <string notr="true">background-color: #C7CAEB</string>
+   </property>
+   <property name="frameShape">
+    <enum>QFrame::StyledPanel</enum>
+   </property>
+   <property name="frameShadow">
+    <enum>QFrame::Raised</enum>
    </property>
   </widget>
  </widget>

+ 40 - 0
View/die-bonder-ui/Src/Res/qss/light.qss

@@ -44,6 +44,46 @@ QTabBar::tab:selected
     border-bottom: 2px solid #2196F3;
 }
 
+
+
+/* 设置分支图标 */
+QTreeView::branch:closed:has-children {
+    border-image: none;
+    image: url(:/images/home_add.png);
+}
+QTreeView::branch:open:has-children {
+    border-image: none;
+    image: url(:/images/home_minus.png);
+}
+
+/* 设置多选框 */
+QTreeView::indicator:unchecked {
+    image: url(:/images/home_NotSelecte.png);
+}
+QTreeView::indicator:checked {
+    image: url(:/images/home_selected.png);
+}
+
+/* 背景透明,行间距 */
+QTreeView {
+    background: transparent;
+    border: none;
+}
+
+/* 设置项目选中的背景色 */
+QTreeView::item:selected {
+    background-color: #A9B4FF;
+}
+
+/* 设置项目的行间距 */
+QTreeView::item {
+    padding-top: 5px;    /* 上边距 */
+    padding-bottom: 5px; /* 下边距 */
+}
+
+
+
+
 /*------------------------------------------全局样式区域------------------------------------------*/
 
 /*登录*/