#include "DbTreeViewManager.h" #include "OriginalWnd/OriginalWnd.h" #include "OriginalWnd/NonInteractiveCheckDelegate.h" #include #include #include #include "Src/common/JMessageTip.h" #include "CViewInterface.h" // 构造函数 DbTreeViewManager::DbTreeViewManager(OriginalWnd* originalWnd, QWidget* widget2, QWidget* parent) : QWidget(parent), m_originalWnd(originalWnd), widget2(widget2), treeViewDown(new QTreeView(this)), model(new QStandardItemModel(this)), restoring(false), m_blockItemChanged(false) { if (!widget2) { // qWarning() << "DbTreeViewManager: widget2 未初始化"; return; } //设置样式 //创建数据库对象 m_sqlOper = &SqlOperation::GetInstance(); // 设置模型 treeViewDown->setModel(model); treeViewDown->setHeaderHidden(true); treeViewDown->setEditTriggers(QAbstractItemView::NoEditTriggers); // 设置树视图的几何位置 treeViewDown->setGeometry(16, 106, widget2->width() - 16, widget2->height() - 106); // 安装事件过滤器以自定义绘制虚线 treeViewDown->viewport()->installEventFilter(this); // 创建统一分隔线 lineFrame1 = createUnifiedSeparator(widget2, 2); lineFrame1->setGeometry(16, 100, 460, 2); // 创建按钮并设置布局 setupButton(); // 创建导航栏 navigationWidget = new QWidget(widget2); navigationWidget->setGeometry(15, 15, 300, 74); // 连接目录前的复选框信号与槽 connect(model, &QStandardItemModel::itemChanged, this, &DbTreeViewManager::onItemChanged); // 目录树连接点击信号 connect(treeViewDown, &QTreeView::clicked, this, &DbTreeViewManager::onTreeViewClicked); // 连接目录 expanded 和 collapsed 信号 connect(treeViewDown, &QTreeView::expanded, this, [=](const QModelIndex &index) { QStandardItem *item = model->itemFromIndex(index); if (!item) return; QStringList path = buildItemPath(item); expandedPaths.insert(path.join("/")); updateSeparatorLine(); // 保存展开路径 saveExpandedPaths(); }); connect(treeViewDown, &QTreeView::collapsed, this, [=](const QModelIndex &index) { QStandardItem *item = model->itemFromIndex(index); if (!item) return; QStringList path = buildItemPath(item); expandedPaths.remove(path.join("/")); updateSeparatorLine(); // 保存展开路径 saveExpandedPaths(); }); // 所有展开操作完成后更新分隔线 QTimer::singleShot(0, this, [=]() { QStandardItem *rootItem = model->invisibleRootItem(); QStandardItem *thirdItem = findFirstThirdLevelItemDFS(rootItem); if (thirdItem) { QJsonObject thirdLevelObj = thirdItem->data(Qt::UserRole + 2).toJsonObject(); if (thirdLevelObj.contains("IsThirdLevel") && thirdLevelObj["IsThirdLevel"].toBool()) { QString multiTableName = ""; if (thirdLevelObj.contains("TableName")) { multiTableName = thirdLevelObj["TableName"].toString(); } QList buttons; int userGrade = 0x1; m_sqlOper->GetThirdDirButtons(multiTableName, userGrade, buttons); displayThirdLevelButtons(buttons); // loadButtonConfigForThirdLevel(thirdLevelObj); } } }); // 应用自定义只读复选框委托 treeViewDown->setItemDelegate(new NonInteractiveCheckDelegate(treeViewDown)); menuArray[0] = {2, false,-1}; menuArray[1] = {5, false,-1}; menuArray[2] = {3, false,-1}; menuArray[3] = {4, false,-1}; menuArray[4] = {6, false,-1}; currentMenuId = -1; } DbTreeViewManager::~DbTreeViewManager() { } // 创建横线样式 QFrame* DbTreeViewManager::createUnifiedSeparator(QWidget *parent, int height) { QFrame *separator = new QFrame(parent); separator->setFrameShape(QFrame::NoFrame); // 移除默认框架 separator->setFixedHeight(height); // 设置固定高度 separator->setStyleSheet("background-color: #C7CAEB;"); separator->hide(); // 初始化为隐藏 return separator; } // 目录树样式 void DbTreeViewManager::applyCustomStyles() { treeViewDown->setStyleSheet(R"( /* 设置分支图标 */ 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; /* 下边距 */ } )"); } // 检查权限 bool DbTreeViewManager::hasPrivilege(const int &UserGrade, const int &userPrivilege) { bool hasPriv; // UserGrade 是以逗号分隔的字符串,如 "1,2,3" if(UserGrade==userPrivilege){ hasPriv = true; }else{ hasPriv = false; } // qDebug() << "Checking privilege. UserGrade:" << UserGrade << "userPrivilege:" << userPrivilege << "result:" << hasPriv; return hasPriv; } //void DbTreeViewManager::updateDb(const QString &TableName, const int &Id,const QString currentValue){ // QSqlDatabase db = QSqlDatabase::database(); // if (!db.isOpen()) { // qWarning() << "数据库未打开"; // } // QString sql = QString("UPDATE %1 SET currentValue = :newValue WHERE id = :id").arg(TableName); // QSqlQuery query; // query.prepare(sql); // query.bindValue(":newValue", currentValue); // query.bindValue(":id", Id); // // 执行更新操作 // if (!query.exec()) { // qWarning() << "Failed to update currentValue:" << query.lastError().text(); // } else { // qDebug() << "currentValue updated successfully."; // } //} void DbTreeViewManager::initializeTree(QString name, const int &userPrivilege) { qDebug() << "Initializing tree with configId:" << name << "and userPrivilege:" << userPrivilege; m_currentConfigName = name; // 设置当前配置ID // 先清空历史 clearHistory(); // 保存之前的选中/展开状态 m_blockItemChanged = true; restoring = true; // 清理当前的分隔线 clearAllSeparators(); // 清空已有模型数据和相关记录 model->clear(); firstLevelSeparators.clear(); expandedPaths.clear(); // 清理并隐藏三级目录窗口 clearThirdLevelMenu(); // **Home 界面逻辑** if (name == "Home") { // 隐藏目录树和分隔线 treeViewDown->hide(); for (auto separator : firstLevelSeparators) { if (separator) separator->hide(); } // 隐藏导航栏 navigationWidget->hide(); // 隐藏按钮 updateButtonsVisibility(); // 将按钮隐藏 // 隐藏特定的分隔线 lineFrame1 if (lineFrame1) { lineFrame1->hide(); } // 从 BondHead 和 Buttons 表中加载 DirectoryId = 1 的数据 QList tableControlDatas; bool allChangeFlag = false; m_sqlOper->GetThirdDirControlData("HomeProduct", userPrivilege, tableControlDatas, allChangeFlag); //QJsonObject data = fetchThirdLevelData(1, userPrivilege); displayThirdLevelFields(tableControlDatas, allChangeFlag, true); // 传递参数表示 Home 界面 // 把当前页面压到 m_backStack 里 PageState st; st.path << "Home"; st.isThirdLevel = true; st.directoryId = 1; st.multiTableName = "HomeProduct"; m_backStack.append(st); if(m_backStack.size() >= 2){ buttonLeft->setIcon(QIcon(":/images/home_left.png")); } } else { // **其他配置逻辑** // 设置 treeViewDown 的几何位置 treeViewDown->setGeometry(16, 106, widget2->width() - 16, widget2->height() - 106); // 显示目录树和分隔线 treeViewDown->show(); for (auto separator : firstLevelSeparators) { if (separator) separator->show(); } // 应用自定义样式 applyCustomStyles(); // 显示导航栏 navigationWidget->show(); // 显示按钮 updateButtonsVisibility(); // 显示特定的分隔线 lineFrame1 if (lineFrame1) { lineFrame1->show(); } // 加载目录数据 并进行权限判断 QString tableName = "Dir_" + name; QList directories; m_sqlOper->GetDirectories(tableName, userPrivilege, directories); //m_sqlOper.loadDirectories(tableName, userPrivilege, directories); buildTreeFromDirectories(directories); //loadDirectories(configId, userPrivilege); // // 更新分隔线 updateSeparatorLine(); m_blockItemChanged = false; restoring = false; // qDebug() << "Tree initialization completed."; // 恢复展开路径 loadExpandedPaths(); // 恢复复选框状态 loadCheckedPaths(); // 自动选中第一个根目录项并更新导航栏 QStandardItem *rootItem = model->invisibleRootItem()->child(0); if (rootItem) { QModelIndex rootIndex = model->indexFromItem(rootItem); treeViewDown->setCurrentIndex(rootIndex); updateNavigationBar(rootIndex); // 如果当前根目录是三级目录,则加载其字段内容 QVariant dataVar = rootItem->data(Qt::UserRole + 2).toJsonObject(); bool isThirdLevel = false; int directoryId = -1; QString multiTableName = ""; if (dataVar.canConvert()) { QJsonObject thirdLevelObj = dataVar.toJsonObject(); if (thirdLevelObj.contains("IsThirdLevel") && thirdLevelObj["IsThirdLevel"].toBool()) { isThirdLevel = true; if (thirdLevelObj.contains("Id")) { directoryId = thirdLevelObj["Id"].toInt(); } if (thirdLevelObj.contains("TableName")) { multiTableName = thirdLevelObj["TableName"].toString(); } } } if (isThirdLevel) { if (directoryId == -1) { // qWarning() << "无效的 DirectoryId,无法加载第三层目录内容。"; return; } // userPrivilege 同样传递 //QJsonObject data = fetchThirdLevelData(directoryId, userPrivilege); QList tableControlDatas; bool allChangeFlag = false; m_sqlOper->GetThirdDirControlData(multiTableName, userPrivilege, tableControlDatas, allChangeFlag); //QJsonObject data = fetchThirdLevelData(1, userPrivilege); displayThirdLevelFields(tableControlDatas, allChangeFlag, false); // 传递参数表示 Home 界面 //QJsonObject data = m_sqlOper.fetchThirdLevelData(multiTableName, directoryId, userPrivilege); //displayThirdLevelFields(data, false); // 传递参数表示非 Home 界面 // 把当前状态压入 m_backStack PageState st; st.path = buildItemPath(rootItem); st.isThirdLevel = true; st.directoryId = directoryId; st.multiTableName = multiTableName; m_backStack.append(st); if(m_backStack.size() >= 2){ buttonLeft->setIcon(QIcon(":/images/home_left.png")); } } } else { // qWarning() << "树形模型中没有根目录项。"; } //寻找第一个三级目录,显示第一个三级目录的按钮 // 自动找第一个三级目录 QStandardItem *rootItem1 = model->invisibleRootItem(); QStandardItem *firstThirdItem = findFirstThirdLevelItemDFS(rootItem1); if (!firstThirdItem) { // qDebug() << "[initializeTree] No third-level item found, do nothing."; return; } // QStandardItem 里获取它的目录信息 QVariant dataVar = firstThirdItem->data(Qt::UserRole + 2); if (!dataVar.canConvert()) { // qWarning() << "[initializeTree] firstThirdItem->data 无法转换为 QJsonObject"; return; } QJsonObject dirObj = dataVar.toJsonObject(); if (!dirObj.contains("Id")) { // qWarning() << "[initializeTree] 第一个三级目录无 Id 字段,无法加载"; return; } int directoryId = dirObj["Id"].toInt(); if (!dirObj.contains("TableName")) { return; } QString multiTableName = dirObj["TableName"].toString(); //根据目录ID找出按钮 QTimer::singleShot(0, this, &DbTreeViewManager::updateSeparatorLine); QList buttons; m_sqlOper->GetThirdDirButtons(multiTableName, userPrivilege, buttons); //QJsonObject data = fetchThirdLevelData(1, userPrivilege); displayThirdLevelButtons(buttons); // 传递参数表示 Home 界面 // 数据库BondHead/Buttons //QJsonObject data = fetchThirdLevelData(directoryId, userPrivilege); //if (!data.contains("buttons")) { // // 第三层没有 buttons 字段 // qWarning() << "[initializeTree] fetchThirdLevelData: no 'buttons', skip"; // return; //} // singleShot 在所有展开操作完成后更新分隔线 // loadButtonConfigForThirdLevel 显示按钮 //loadButtonConfigForThirdLevel(data); } } // 从数据库加载目录 包含权限判断 void DbTreeViewManager::loadDirectories(int configId, const int &userPrivilege) { // qDebug() << "Loading directories for configId:" << configId << "with userPrivilege:" << userPrivilege; QSqlDatabase db = QSqlDatabase::database(); if (!db.isOpen()) { qWarning() << "数据库未打开"; return; } QSqlQuery query(db); query.prepare(R"( SELECT Id, Name, ParentId, IsThirdLevel, Separator, UserGrade, Circle FROM Directories WHERE ConfigId = :configId )"); query.bindValue(":configId", configId); if (!query.exec()) { qWarning() << "查询 Directories 失败:" << query.lastError().text(); return; } // 以 QJsonObject 保存所有目录 QList directories; while (query.next()) { QJsonObject obj; int id = query.value("Id").toInt(); obj["Id"] = id; obj["Name"] = query.value("Name").toString(); obj["ParentId"] = query.value("ParentId").isNull() ? -1 : query.value("ParentId").toInt(); obj["IsThirdLevel"] = query.value("IsThirdLevel").toBool(); obj["Separator"] = query.value("Separator").toInt(); obj["UserGrade"] = query.value("UserGrade").toString(); obj["Circle"] = query.value("Circle").toInt(); qDebug() << "加载目录:"<< obj["Name"].toString() << " ParentId:" << obj["ParentId"].toInt()<< " Separator:" << obj["Separator"].toInt(); qDebug() << " Circle:" << obj["Circle"].toInt(); // 权限判断:只有当记录的 UserGrade 中包含当前用户权限时才加入 bool ok; if (hasPrivilege(obj["UserGrade"].toString().toInt(&ok,16), userPrivilege)) directories.append(obj); else qDebug() << "目录跳过(权限不足):" << obj["Name"].toString(); } // qDebug() << "Loaded directories count:" << directories.size(); // 根据目录列表构建树模型 buildTreeFromDirectories(directories); } void DbTreeViewManager::buildTreeFromDirectories(const QList &directories) { // 建立 Id->QStandardItem 的映射 QMap idItemMap; for (const QJsonObject &dir : directories) { QStandardItem *item = new QStandardItem(dir["Name"].toString()); item->setData(dir["Id"].toInt(), Qt::UserRole + 1); // 保存目录Id // 如果是三级目录,将整个 JSON 对象存到 UserRole+2 if (dir["IsThirdLevel"].toBool()) { item->setData(dir, Qt::UserRole + 2); } else { item->setData(false, Qt::UserRole + 2); // 标记为非三级目录 } item->setCheckable(true); // 复选框状态由程序逻辑设置 item->setCheckState(Qt::Unchecked); idItemMap.insert(dir["Id"].toInt(), item); } // 建立父子关系 for (const QJsonObject &dir : directories) { int parentId = dir["ParentId"].toInt(); int currentId = dir["Id"].toInt(); QStandardItem *childItem = idItemMap.value(currentId); if (childItem == nullptr) { qDebug() << "child is nullptr"; } if (parentId == -1) { // 说明这是一级目录 model->invisibleRootItem()->appendRow(childItem); qDebug() << " !!!!! first :" << "child : " << currentId; // 如果一级目录的 "Separator" == 1,则为其创建一条分割线 if (dir["Separator"].toInt() == 1) { QFrame *sep = createUnifiedSeparator(widget2, 2); sep->hide(); firstLevelSeparators.insert(childItem, sep); } } else { // 非一级目录 => 子目录 QStandardItem *parentItem = idItemMap.value(parentId); if (parentItem) { parentItem->appendRow(childItem); qDebug() << "parent:" << parentId << "child : " << currentId; } else qWarning() << "无法找到 ParentId:" << parentId << "的父目录项"; } } } // 查询三级目录下的 BondHead 和 Buttons 数据 均判断权限 //QJsonObject DbTreeViewManager::fetchThirdLevelData(int directoryId, const int &userPrivilege) //{ // QJsonObject data; // QJsonArray fieldsArray; // QJsonArray buttonsArray; // QString temp; // bool allChangeFlag = true; // 默认所有 ChangeFlag 为 true // // QSqlDatabase db = QSqlDatabase::database(); // if (!db.isOpen()) { // qWarning() << "数据库未打开"; // return data; // } // // 查询 TableName 表 // QSqlQuery queryBondtest(db); // queryBondtest.prepare(R"( // SELECT TableName // FROM Directories // WHERE Id = :dirId // )"); // queryBondtest.bindValue(":dirId",directoryId); // if (queryBondtest.exec()) { // while (queryBondtest.next()) { // temp = queryBondtest.value("TableName").toString(); // } // } // QStringList tableName = temp.split(","); // QString currentTableName; // for (const QString &item : tableName) { // if (item.isEmpty()) { // qDebug() << "Encountered an empty string, stopping traversal."; // break; // 遇到空字符串时退出循环 // }else{ // currentTableName = item; // QString sql = QString("SELECT Id, DirectoryId, Describe, Type, Value,CurrentValue,UpLimit,DownLimit,units, Groupld, UserGrade, ChangeFlag FROM %1 WHERE DirectoryId = :dirId").arg(currentTableName); // // 查询 BondHead 表 // QSqlQuery queryBond(db); // queryBond.prepare(sql); // queryBond.bindValue(":dirId", directoryId); // if (queryBond.exec()) { // while (queryBond.next()) { // bool ok; // int dbUserGrade = queryBond.value("UserGrade").toString().toInt(&ok, 16); // // 只有当数据库记录的 UserGrade 包含当前用户权限时才加载该字段 // if (!hasPrivilege(dbUserGrade, userPrivilege)) // continue; // QJsonObject field; // field["Id"] = queryBond.value("Id").toInt(); // field["DirectoryId"] = queryBond.value("DirectoryId").toInt(); // field["Describe"] = queryBond.value("Describe").toString(); // field["Type"] = queryBond.value("Type").toString(); // field["Value"] = queryBond.value("Value").toString(); // field["CurrentValue"] = queryBond.value("CurrentValue").toString(); // field["UpLimit"] = queryBond.value("UpLimit").toString(); // field["DownLimit"] = queryBond.value("DownLimit").toString(); // field["units"] = queryBond.value("units").toString(); // field["Groupld"] = queryBond.value("Groupld").toInt(); // field["ChangeFlag"] = queryBond.value("ChangeFlag").toInt(); // field["TableName"] = currentTableName; // fieldsArray.append(field); // // // 如果有任一字段 ChangeFlag 为 0,则 allChangeFlag = false // if (queryBond.value("ChangeFlag").toInt() == 0) // allChangeFlag = false; // } // // qDebug() << "Fetched fields:" << fieldsArray; // } else { // qWarning() << "查询 BondHead 失败:" << queryBond.lastError().text(); // } // } // } // //QString sql = QString("SELECT Id, DirectoryId, Describe, Type, Value,units, Groupld, UserGrade, ChangeFlag FROM %1 WHERE DirectoryId = :dirId").arg(currentTableName); // // // 查询 BondHead 表 // // QSqlQuery queryBond(db); // // queryBond.prepare(sql); // // queryBond.bindValue(":dirId", directoryId); // // if (queryBond.exec()) { // // while (queryBond.next()) { // // bool ok; // // int dbUserGrade = queryBond.value("UserGrade").toString().toInt(&ok, 16); // // // 只有当数据库记录的 UserGrade 包含当前用户权限时才加载该字段 // // if (!hasPrivilege(dbUserGrade, userPrivilege)) // // continue; // // QJsonObject field; // // field["Id"] = queryBond.value("Id").toInt(); // // field["DirectoryId"] = queryBond.value("DirectoryId").toInt(); // // field["Describe"] = queryBond.value("Describe").toString(); // // field["Type"] = queryBond.value("Type").toString(); // // field["Value"] = queryBond.value("Value").toString(); // // field["units"] = queryBond.value("units").toString(); // // field["Groupld"] = queryBond.value("Groupld").toInt(); // // field["ChangeFlag"] = queryBond.value("ChangeFlag").toInt(); // // fieldsArray.append(field); // // // // 如果有任一字段 ChangeFlag 为 0,则 allChangeFlag = false // // if (queryBond.value("ChangeFlag").toInt() == 0) // // allChangeFlag = false; // // } // // // qDebug() << "Fetched fields:" << fieldsArray; // // } else { // // qWarning() << "查询 BondHead 失败:" << queryBond.lastError().text(); // // } // // // 查询 Buttons 表 // QSqlQuery queryBtn(db); // queryBtn.prepare(R"( // SELECT ButtonId, Icon, Text, Enabled, UserGrade // FROM Buttons // WHERE DirectoryId = :dirId // )"); // queryBtn.bindValue(":dirId", directoryId); // if (queryBtn.exec()) { // while (queryBtn.next()) { // bool ok; // int btnUserGrade = queryBtn.value("UserGrade").toString().toInt(&ok, 16); // if (!hasPrivilege(btnUserGrade, userPrivilege)) // continue; // QJsonObject button; // button["id"] = queryBtn.value("ButtonId").toString(); // button["icon"] = queryBtn.value("Icon").toString(); // button["text"] = queryBtn.value("Text").toString(); // button["enabled"] = queryBtn.value("Enabled").toBool(); // buttonsArray.append(button); // } // // qDebug() << "Fetched buttons:" << buttonsArray; // } else { // qWarning() << "查询 Buttons 失败:" << queryBtn.lastError().text(); // } // // data["fields"] = fieldsArray; // data["buttons"] = buttonsArray; // data["IsThirdLevel"] = true; // data["allChangeFlag"] = allChangeFlag; // return data; //} // 事件过滤器,用于自定义绘制虚线 bool DbTreeViewManager::eventFilter(QObject *watched, QEvent *event) { // 拦截 Paint 事件 if (watched == treeViewDown->viewport() && event->type() == QEvent::Paint) { // 进行默认绘制 bool handled = QWidget::eventFilter(watched, event); // 使用 QPainter 叠加画“拐角线” QPainter painter(treeViewDown->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 DbTreeViewManager::paintAllBranches(const QModelIndex &parentIndex, QPainter &painter) { int rowCount = model->rowCount(parentIndex); for(int i = 0; i < rowCount; ++i) { // 当前子节点 QModelIndex childIndex = 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); } } // 在“父节点 -> 子节点”间画一条“L”型拐角线,调整横向线段的长度 void DbTreeViewManager::drawParentChildLine(const QModelIndex &childIndex, QPainter &painter) { QModelIndex parentIndex = childIndex.parent(); if (!parentIndex.isValid()) { // “顶层节点”定义一个固定的起点 (rootX, rootY) int indent = treeViewDown->indentation(); int depth = 0; // 顶层节点深度为0 int branchX = (depth + 1) * indent - indent / 2; // 计算 branchX 基于缩进和深度 // 定义 rootY 为节点中心 Y QRect childRect = treeViewDown->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 = treeViewDown->visualRect(parentIndex); QRect childRect = treeViewDown->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 = treeViewDown->indentation(); int branchX = depth * indent - indent / 2; // branchX 不超出视图范围 branchX = std::max(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 DbTreeViewManager::drawSiblingLine(const QModelIndex &childIndex, QPainter &painter) { QModelIndex parentIndex = childIndex.parent(); if (!parentIndex.isValid()) { return; // 没有父节点 } // 下一个兄弟 int row = childIndex.row(); int lastRow = model->rowCount(parentIndex) - 1; if (row >= lastRow) { return; // 说明是最后一个兄弟,不用画延伸线 } QModelIndex nextSibling = model->index(row + 1, 0, parentIndex); QRect currRect = treeViewDown->visualRect(childIndex); QRect nextRect = treeViewDown->visualRect(nextSibling); if (!currRect.isValid() || !nextRect.isValid()) { return; } // 计算节点深度 int depth = 0; QModelIndex p = parentIndex; while (p.isValid()) { depth++; p = p.parent(); } int indent = treeViewDown->indentation(); int branchX = depth * indent - indent / 2; // 确保 branchX 不超出视图范围 branchX = std::max(branchX, 0); // 从当前节点底部向下延伸到下一个兄弟节点顶部 int startY = currRect.bottom(); int endY = nextRect.top(); painter.drawLine(QPoint(branchX, startY), QPoint(branchX, endY)); } // 递归查找第一个三级目录项 QStandardItem* DbTreeViewManager::findFirstThirdLevelItemDFS(QStandardItem *parentItem) { if (!parentItem) { return nullptr; } // 遍历当前 parentItem 的所有子 for (int i = 0; i < parentItem->rowCount(); ++i) { QStandardItem *child = parentItem->child(i); if (!child) continue; // 检查这个子节点是否是三级目录 QVariant data = child->data(Qt::UserRole + 2); if (data.canConvert()) { QJsonObject obj = data.toJsonObject(); if (obj.contains("IsThirdLevel") && obj["IsThirdLevel"].toBool()) { // 找到第一个 IsThirdLevel = true 的节点就返回 return child; } } // 如果不是 IsThirdLevel,继续往子节点里找 QStandardItem* deeperFound = findFirstThirdLevelItemDFS(child); if (deeperFound) { return deeperFound; } } return nullptr; } void DbTreeViewManager::onItemChanged(QStandardItem *item) { if (m_blockItemChanged || restoring) { return; // 防止递归和恢复期间触发 } m_blockItemChanged = true; Qt::CheckState state = item->checkState(); // 更新所有子项的复选框状态 for (int i = 0; i < item->rowCount(); ++i) { QStandardItem *child = item->child(i); if (child) { child->setCheckState(state); // 递归更新子项 onItemChanged(child); } } // 更新所有父项的复选框状态 QModelIndex parentIndex = item->index().parent(); while (parentIndex.isValid()) { QStandardItem *parentItem = model->itemFromIndex(parentIndex); if (!parentItem) break; int checkedCount = 0; int totalCount = parentItem->rowCount(); for (int i = 0; i < totalCount; ++i) { QStandardItem *child = parentItem->child(i); if (child && child->checkState() == Qt::Checked) { checkedCount++; } } if (checkedCount == totalCount) { parentItem->setCheckState(Qt::Checked); } else { parentItem->setCheckState(Qt::Unchecked); } parentIndex = parentIndex.parent(); } m_blockItemChanged = false; // 记录复选框状态 saveCheckedPaths(); } // 初始化和设置按钮 void DbTreeViewManager::setupButton() { // 创建按钮并设置属性 auto createButton = [&](QPushButton*& button, const QString& iconPath, const QRect& geometry) { button = new QPushButton(this); button->setIcon(QIcon(iconPath)); button->setGeometry(geometry); button->setStyleSheet(R"( QPushButton { position: absolute; border-radius: 6px; opacity: 1; background: #FFFFFF; border: 1px solid #BABBDC; } QPushButton:hover { background-color: #A9B4FF; /* 鼠标悬停效果 */ } )"); button->show(); }; // 根据原始代码调整按钮的位置和大小 createButton(ButtonBack, ":/images/home_openFile.png", QRect(328, 6, 76, 30)); createButton(buttonUp, ":/images/home_up.png", QRect(408, 6, 36, 30)); createButton(buttonDown, ":/images/home_down.png", QRect(408, 40, 36, 30)); createButton(buttonLeft, ":/images/home_left_hide.png", QRect(328, 40, 36, 30)); createButton(buttonRight, ":/images/home_right.png", QRect(368, 40, 36, 30)); // 连接按钮的点击信号到相应的槽函数 connect(ButtonBack, &QPushButton::clicked, this, &DbTreeViewManager::onButtonBackClicked); connect(buttonUp, &QPushButton::clicked, this, &DbTreeViewManager::onButtonUpClicked); connect(buttonDown, &QPushButton::clicked, this, &DbTreeViewManager::onButtonDownClicked); connect(buttonLeft, &QPushButton::clicked, this, &DbTreeViewManager::onButtonLeftClicked); connect(buttonRight, &QPushButton::clicked, this, &DbTreeViewManager::onButtonRightClicked); } void DbTreeViewManager::updateButtonsVisibility() { if (m_currentConfigName == "Home") { // Home 界面,隐藏所有按钮 ButtonBack->hide(); buttonUp->hide(); buttonDown->hide(); buttonLeft->hide(); buttonRight->hide(); } else { // 其他配置,显示所有按钮 ButtonBack->show(); buttonUp->show(); buttonDown->show(); buttonLeft->show(); buttonRight->show(); } } QStandardItem* DbTreeViewManager::deepCopyItem(const QStandardItem *item){ if (!item) { return nullptr; } // 创建一个新的 QStandardItem QStandardItem *newItem = new QStandardItem(item->text()); newItem->setIcon(item->icon()); newItem->setToolTip(item->toolTip()); newItem->setEditable(item->isEditable()); newItem->setCheckable(item->isCheckable()); newItem->setCheckState(item->checkState()); // 递归复制子项 for (int i = 0; i < item->rowCount(); ++i) { QStandardItem *childItem = item->child(i); QStandardItem *newChildItem = deepCopyItem(childItem); newItem->appendRow(newChildItem); } return newItem; } void DbTreeViewManager::loadpage(const int &configId){ for(int i=0;i<5;i++){ if(configId == menuArray[i].menuId){ // QJsonObject data = fetchThirdLevelData(menuArray[i].index, 0x1); //displayThirdLevelFields(data, false); } } } void DbTreeViewManager::onTreeViewClicked(const QModelIndex &index) { QStandardItem *item = model->itemFromIndex(index); if (!item) return; // 是否第三层,提取第三层的目录ID及目录表格名字 bool isThird = false; int dirId = -1; //QString dirTableName = ""; QString mutliTableName = ""; QVariant dataVar = item->data(Qt::UserRole + 2); if (dataVar.canConvert()) { QJsonObject obj = dataVar.toJsonObject(); if (obj.contains("IsThirdLevel") && obj["IsThirdLevel"].toBool()) { isThird = true; if (obj.contains("Id")) { dirId = obj["Id"].toInt(); } if (obj.contains("TableName")) { mutliTableName = obj["TableName"].toString(); } } } updateNavigationBar(index); if (isThird) { //!!!修改权限 int userPrivilege = 0x1; // 示例 if (dirId < 0) { qWarning() << "无效directoryId"; return; } if (mutliTableName == "") { qWarning() << "无效directoryId"; return; } QList tableControlDatas; bool allChangeFlag = false; m_sqlOper->GetThirdDirControlData(mutliTableName, userPrivilege, tableControlDatas, allChangeFlag); displayThirdLevelFields(tableControlDatas, allChangeFlag, false); // 传递参数表示 Home 界面 //QJsonObject data = m_sqlOper.fetchThirdLevelData(mutliTableName, dirId, userPrivilege); //QJsonObject data = fetchThirdLevelData(dirId, userPrivilege); //displayThirdLevelFields(data, false); for(int i=0;i<5;i++){ if(currentMenuId == menuArray[i].menuId){ menuArray[i].isthird = true; menuArray[i].index = dirId; } } // 将“新页面”压入后退栈, 并清空前进栈 PageState st; st.path = buildItemPath(item); st.isThirdLevel = true; st.directoryId = dirId; st.multiTableName = mutliTableName; m_backStack.append(st); if(m_backStack.size() >= 2){ buttonLeft->setIcon(QIcon(":/images/home_left.png")); } m_forwardStack.clear(); buttonRight->setIcon(QIcon(":/images/home_right.png")); } else { // 不是第三层,只是选中目录 // 清理第三层窗口 if (m_thirdLevelFieldWnd) { m_thirdLevelFieldWnd->close(); m_thirdLevelFieldWnd->deleteLater(); m_thirdLevelFieldWnd = nullptr; } // 同样更新历史 PageState st; st.path = buildItemPath(item); st.isThirdLevel = false; st.directoryId = -1; st.multiTableName = mutliTableName; m_backStack.append(st); if(m_backStack.size() >= 2){ buttonLeft->setIcon(QIcon(":/images/home_left.png")); } m_forwardStack.clear(); buttonRight->setIcon(QIcon(":/images/home_right.png")); } } void DbTreeViewManager::onTreeViewClicked_updown(const QModelIndex &index){ QStandardItem *item = model->itemFromIndex(index); if (!item) return; // 是否第三层 bool isThird = false; int dirId = -1; QString multiTableName = ""; QVariant dataVar = item->data(Qt::UserRole + 2); if (dataVar.canConvert()) { QJsonObject obj = dataVar.toJsonObject(); if (obj.contains("IsThirdLevel") && obj["IsThirdLevel"].toBool()) { isThird = true; if (obj.contains("Id")) { dirId = obj["Id"].toInt(); } if (obj.contains("TableName")) { multiTableName = obj["TableName"].toString(); } } } updateNavigationBar(index); if (isThird) { int userPrivilege = 0x1; // 示例 if (dirId < 0) { qWarning() << "无效directoryId"; return; } if (multiTableName == "") { qWarning() << "无效multiTableName"; return; } QList tableControlDatas; bool allChangeFlag = false; m_sqlOper->GetThirdDirControlData(multiTableName, userPrivilege, tableControlDatas, allChangeFlag); displayThirdLevelFields(tableControlDatas, allChangeFlag, false); // 传递参数表示 Home 界面 // QJsonObject data = m_sqlOper.fetchThirdLevelData(multiTableName, dirId, userPrivilege); //displayThirdLevelFields(data, false); // QJsonObject data = fetchThirdLevelData(dirId, userPrivilege); // 将“新页面”压入后退栈, 并清空前进栈 PageState st; st.path = buildItemPath(item); st.isThirdLevel = true; st.directoryId = dirId; st.multiTableName = multiTableName; m_backStack.append(st); if(m_backStack.size() >= 2){ buttonLeft->setIcon(QIcon(":/images/home_left.png")); } m_forwardStack.clear(); buttonRight->setIcon(QIcon(":/images/home_right.png")); } else { // 不是第三层,只是选中目录 // 清理第三层窗口 if (m_thirdLevelFieldWnd) { m_thirdLevelFieldWnd->close(); m_thirdLevelFieldWnd->deleteLater(); m_thirdLevelFieldWnd = nullptr; } // 同样更新历史 PageState st; st.path = buildItemPath(item); st.isThirdLevel = false; st.directoryId = -1; st.multiTableName = multiTableName; m_backStack.append(st); if(m_backStack.size() >= 2){ buttonLeft->setIcon(QIcon(":/images/home_left.png")); } m_forwardStack.clear(); buttonRight->setIcon(QIcon(":/images/home_right.png")); } } void DbTreeViewManager::updateNavigationBar(const QModelIndex &index) { QStandardItem *item = model->itemFromIndex(index); if (!item) { qWarning() << "导航栏更新失败:未找到对应项"; return; } // 清理现有布局 if (navigationWidget->layout()) { QLayoutItem *child; while ((child = navigationWidget->layout()->takeAt(0)) != nullptr) { if (child->widget()) { child->widget()->deleteLater(); } delete child; } delete navigationWidget->layout(); } // 构建路径列表,从当前项回溯到根节点 QList path; QStandardItem *temp = item; while (temp) { path.prepend(temp); // 从根节点开始 temp = temp->parent(); } QVBoxLayout *newLayout = new QVBoxLayout; // 创建新的导航栏布局 newLayout->setContentsMargins(0, 0, 3, 3); newLayout->setSpacing(0); // 确保显示三行 for (int i = 0; i < 3; ++i) { QLabel *label = new QLabel; if (i < path.size()) { QString text = path[i]->text(); if (i == 1) text = " " + text; // 二级目录缩进 if (i == 2) text = " " + text; // 三级目录缩进 label->setText(text); } else { label->setText(""); // 填充空白行 } QFont font = label->font(); // 设置字体和样式 font.setPointSize(14); font.setFamily("思源黑体"); font.setBold(true); // 设置文字为粗体 font.setLetterSpacing(QFont::PercentageSpacing,105); // 设置字间距100%为默认 label->setFont(font); label->setFixedHeight(navigationWidget->height() / 3); newLayout->addWidget(label); } // 设置布局并更新导航栏 navigationWidget->setLayout(newLayout); navigationWidget->update(); } void DbTreeViewManager::clearAllSeparators() { // 遍历 firstLevelSeparators 中所有 QFrame, // 隐藏后调用 deleteLater() for (auto separator : firstLevelSeparators.values()) { if(separator) { separator->hide(); separator->deleteLater(); } } // 清空映射 firstLevelSeparators.clear(); } void DbTreeViewManager::updateSeparatorLine() { // 如果目录树被隐藏,就把分割线都藏起来 if (!treeViewDown->isVisible()) { for (auto it = firstLevelSeparators.begin(); it != firstLevelSeparators.end(); ++it) { QFrame *sep = it.value(); if (sep) sep->hide(); } return; } // 遍历所有“一级目录”与其分隔线 for (auto it = firstLevelSeparators.begin(); it != firstLevelSeparators.end(); ++it) { QStandardItem *firstLevelItem = it.key(); QFrame *separator = it.value(); if (!firstLevelItem || !separator) continue; // 拿到可视区域 QModelIndex firstLevelIndex = model->indexFromItem(firstLevelItem); QRect firstLevelRect = treeViewDown->visualRect(firstLevelIndex); // 如果这个一级目录滚动到看不见了,就把分割线也藏起来 if (!firstLevelRect.isValid()) { separator->hide(); continue; } // 如果展开并且它有子节点,就找“最后一个可见子项” if (treeViewDown->isExpanded(firstLevelIndex) && firstLevelItem->hasChildren()) { QModelIndex lastVisibleChild = findLastVisibleChild(firstLevelIndex); if (lastVisibleChild.isValid()) { QRect lastChildRect = treeViewDown->visualRect(lastVisibleChild); if (lastChildRect.isValid()) { // 将分割线放在最后一个子项下面 separator->setGeometry(16,lastChildRect.bottom() + 115,widget2->width() - 40,1); separator->show(); continue; } } } // 如果收起或找不到可见子项,就放在本一级目录下面 separator->setGeometry(16,firstLevelRect.bottom() + 115,widget2->width() - 40,1); separator->show(); } } QModelIndex DbTreeViewManager::findLastVisibleChild(const QModelIndex &parentIndex) { if (!parentIndex.isValid()) return QModelIndex(); int childCount = model->rowCount(parentIndex); QModelIndex lastVisible; for (int i = childCount - 1; i >= 0; --i) { QModelIndex childIndex = model->index(i, 0, parentIndex); if (!treeViewDown->isRowHidden(i, parentIndex)) { if (treeViewDown->isExpanded(childIndex) && model->rowCount(childIndex) > 0) { QModelIndex deeper = findLastVisibleChild(childIndex); if (deeper.isValid()) { return deeper; } } lastVisible = childIndex; break; } } return lastVisible; } //void DbTreeViewManager::displayThirdLevelFields(const QJsonObject &data, bool isHome) //{ // if (data.isEmpty()) { // qWarning() << "字段数据为空,无法显示"; // return; // } // // if (!data.contains("IsThirdLevel") || !data["IsThirdLevel"].toBool()) { // qWarning() << "不是三级目录,跳过按钮加载"; // return; // } // // bool allChangeFlag = false; // if (data.contains("allChangeFlag") && data["allChangeFlag"].isBool()) { // allChangeFlag = data["allChangeFlag"].toBool(); // } // else { // qWarning() << "数据中缺少 'allChangeFlag' 字段或类型不正确"; // } // // // 若已有第三层窗口,先关闭并释放 // if (m_thirdLevelFieldWnd) { // m_thirdLevelFieldWnd->close(); // m_thirdLevelFieldWnd->deleteLater(); // m_thirdLevelFieldWnd = nullptr; // } // // // 获取当前选中的目录项,设置状态 // QModelIndex currentIndex = treeViewDown->currentIndex(); // if (currentIndex.isValid()) { // QStandardItem* currentItem = model->itemFromIndex(currentIndex); // if (currentItem) { // currentItem->setCheckState(allChangeFlag ? Qt::Checked : Qt::Unchecked); // qDebug() << "设置当前目录项复选框状态为:" << (allChangeFlag ? "Checked" : "Unchecked"); // } // } // else { // qWarning() << "当前没有选中的目录项"; // } // // // 隐藏目录树及所有分隔线 // treeViewDown->hide(); // for (auto separator : firstLevelSeparators) { // if (separator) // separator->hide(); // } // // // 显示按钮 // loadButtonConfigForThirdLevel(data); // // // 清理之前的控件列表 // m_fieldWidgets.clear(); // // // 创建新的 "字段展示" 窗口,并赋值给 m_thirdLevelFieldWnd // m_thirdLevelFieldWnd = new QWidget(widget2); // m_thirdLevelFieldWnd->setWindowTitle("字段展示"); // m_thirdLevelFieldWnd->setStyleSheet("background-color: transparent;"); // if (isHome) { // // Home 界面,填满 widget2 // m_thirdLevelFieldWnd->setGeometry(0, 0, widget2->width(), widget2->height()); // } // else { // // 其他配置界面,设置与 treeViewDown 相同的几何位置 // m_thirdLevelFieldWnd->setGeometry(treeViewDown->geometry()); // } // // // 创建滚动区域 // QScrollArea *scrollArea = new QScrollArea(m_thirdLevelFieldWnd); // scrollArea->setWidgetResizable(true); // scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); // // // 创建滚动容器并设置布局 // QWidget *scrollWidget = new QWidget; // scrollWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); // QVBoxLayout *scrollLayout = new QVBoxLayout(scrollWidget); // scrollLayout->setSpacing(10); // scrollLayout->setContentsMargins(10, 10, 10, 10); // // // //!!!提成一个类 // int previousGroupId = -1; // // 遍历字段数组 // if (data.contains("fields") && data["fields"].isArray()) { // QJsonArray fields = data["fields"].toArray(); // for (const QJsonValue &val : fields) { // QJsonObject field = val.toObject(); // int fieldId = field["Id"].toInt(); // QString fieldName = field["Name"].toString(); // QString fieldType = field["Type"].toString(); // QString fieldValue = field["Value"].toString(); // //QString fieldCurrentValue = field["CurrentValue"].toString(); // QString fieldTableName = field["TableName"].toString(); // QString fieldUpLimit = field["UpLimit"].toString(); // QString fieldDownLimit = field["DownLimit"].toString(); // QString fieldUnits = field["units"].toString(); // int groupId = field["Groupld"].toInt(); // // // 如果组变化,插入分隔线 // if (previousGroupId != -1 && groupId != previousGroupId) { // QFrame *separator = createUnifiedSeparator(scrollWidget, 2); // QHBoxLayout *separatorLayout = new QHBoxLayout; // separatorLayout->setContentsMargins(0, 5, 0, 5); // separatorLayout->addWidget(separator); // scrollLayout->addLayout(separatorLayout); // separator->show(); // } // previousGroupId = groupId; // // // 每个字段一行 // QHBoxLayout *fieldLayout = new QHBoxLayout; // fieldLayout->setSpacing(5); // // QLabel *label = new QLabel(fieldName); // label->setAlignment(Qt::AlignVCenter | Qt::AlignLeft); // label->setFixedHeight(24); // label->setMinimumWidth(120); // fieldLayout->addWidget(label); // fieldLayout->addStretch(1); // // QWidget *rightWidget = new QWidget; // QHBoxLayout *rightLayout = new QHBoxLayout(rightWidget); // rightLayout->setContentsMargins(0, 0, 20, 0); // rightLayout->setSpacing(5); // // QWidget *createdWidget = nullptr; // // if (fieldType == "input") { // // 检查 Value 中是否包含逗号分隔(比如 "请输入内容1,分钟") // if (fieldUnits!= "") { // // // 采用逗号分割,trim去除空白 // // QStringList parts = fieldValue.split(",", Qt::SkipEmptyParts); // // QString leftText = parts.at(0).trimmed(); // // QString rightText = (parts.size() > 1 ? parts.at(1).trimmed() : QString()); // // // 创建 QLineEdit 显示左边文本 // QLineEdit *lineEdit = new QLineEdit(); // if((fieldUpLimit=="")&&(fieldDownLimit=="")){ // lineEdit->setText(fieldValue); // lineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); // lineEdit->setFixedSize(105, 28); // lineEdit->setAlignment(Qt::AlignLeft); // //!!!提到前面 // lineEdit->setStyleSheet(R"( // QLineEdit { // background: #FFFFFF; // border: 1px solid #BABBDC; // border-radius: 6px; // padding: 2px 5px; // } // )"); // }else{//上下限至少设置了一个值 // if(fieldValue == ""){ // lineEdit->setPlaceholderText("请输入数字"); // }else{ // lineEdit->setText(fieldValue); // } // // // lineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); // lineEdit->setFixedSize(105, 28); // lineEdit->setAlignment(Qt::AlignLeft); // lineEdit->setStyleSheet(R"( // QLineEdit { // background: #FFFFFF; // border: 1px solid #BABBDC; // border-radius: 6px; // padding: 2px 5px; // } // )"); // } // // // 创建 QLabel 显示右边文本(比如 "分钟") // QLabel *unitLabel = new QLabel(fieldUnits); // unitLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); // unitLabel->setFixedHeight(28); // unitLabel->setStyleSheet("QLabel { font-size: 14px; }"); // // // 把 QLineEdit 和 QLabel 水平排列,确保 Qlabel 显示在 QLineEdit 右侧 // QHBoxLayout *inputLayout = new QHBoxLayout; // inputLayout->setSpacing(10); // inputLayout->setContentsMargins(0,0,0,0); // inputLayout->addWidget(lineEdit); // inputLayout->addWidget(unitLabel); // // // 用一个容器部件来装下这个布局 // QWidget *inputWidget = new QWidget; // inputWidget->setLayout(inputLayout); // rightLayout->addWidget(inputWidget); // // // 保存控件指针到 m_fieldWidgets(可选) // m_fieldWidgets.append(lineEdit); // m_fieldWidgets.append(unitLabel); // createdWidget = inputWidget; // // // 连接 textChanged 信号到 lambda 函数 // connect(lineEdit, &QLineEdit::textChanged, [this,lineEdit,fieldTableName,fieldId,fieldUpLimit,fieldDownLimit]() { // if((fieldUpLimit!="")&&(fieldDownLimit!="")){ // int uplimit = fieldUpLimit.toInt(); // int downlimit = fieldDownLimit.toInt(); // int inputvalue = (lineEdit->text()).toInt(); // if((inputvalue<=uplimit)&&(inputvalue>=downlimit)){ // updateDb(fieldTableName,fieldId,lineEdit->text()); // }else{ // lineEdit->setPlaceholderText("超出设定范围,请重新输入"); // } // }else if(fieldDownLimit!=""){ // int downlimit = fieldDownLimit.toInt(); // int inputvalue = (lineEdit->text()).toInt(); // if(inputvalue>=downlimit){ // updateDb(fieldTableName,fieldId,lineEdit->text()); // }else{ // lineEdit->setPlaceholderText("超出设定范围,请重新输入"); // } // }else if(fieldUpLimit!=""){ // int uplimit = fieldUpLimit.toInt(); // int inputvalue = (lineEdit->text()).toInt(); // if(inputvalue<=uplimit){ // updateDb(fieldTableName,fieldId,lineEdit->text()); // }else{ // lineEdit->setPlaceholderText("超出设定范围,请重新输入"); // } // }else{ // updateDb(fieldTableName,fieldId,lineEdit->text()); // } // // }); // } else { // // 如果不包含逗号,按原有逻辑只创建 QLineEdit // QLineEdit *lineEdit1 = new QLineEdit(fieldValue); // lineEdit1->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); // lineEdit1->setFixedSize(140, 28); // lineEdit1->setAlignment(Qt::AlignLeft); // lineEdit1->setStyleSheet(R"( // QLineEdit { // background: #FFFFFF; // border: 1px solid #BABBDC; // border-radius: 6px; // padding: 2px 5px; // } // )"); // rightLayout->addWidget(lineEdit1); // createdWidget = lineEdit1; // // // 连接 textChanged 信号到 lambda 函数 // connect(lineEdit1, &QLineEdit::textChanged, [this,lineEdit1,fieldTableName,fieldId]() { // updateDb(fieldTableName,fieldId,lineEdit1->text()); // loginput(fieldTableName,fieldId,lineEdit1->text()); // }); // } // } // else if (fieldType == "radio") { // // 用逗号分隔的选项 // QStringList optionList = fieldValue.split(QRegExp("[,,]"), Qt::SkipEmptyParts); // QHBoxLayout *radioLayout = new QHBoxLayout; // radioLayout->setSpacing(5); // QButtonGroup *radioGroup = new QButtonGroup(rightWidget); // for (const QString &optionText : optionList) { // QString trimmedOpt = optionText.trimmed(); // if (trimmedOpt.isEmpty()) continue; // QRadioButton *radioButton = new QRadioButton(trimmedOpt); // radioGroup->addButton(radioButton); // radioLayout->addWidget(radioButton); // m_fieldWidgets.append(radioButton); // if(fieldValue == trimmedOpt){ // radioButton->setChecked(true); // } // } // // 使用Lambda函数连接 buttonToggled 信号 // connect(radioGroup, static_cast(&QButtonGroup::buttonToggled),[this,fieldTableName,fieldId](QAbstractButton *button,bool checked) { // if (checked) { // // qDebug() << "Button toggled:" << button->text(); // // 在这里添加你想要执行的操作 // updateDb(fieldTableName,fieldId,button->text()); // } // }); // rightLayout->addLayout(radioLayout); // } // else if (fieldType == "checkbox") { // bool isChecked; // if(fieldValue == ""){ // isChecked = (fieldValue == "1"); // }else{ // isChecked = (fieldValue == "1"); // } // // QCheckBox *checkBox = new QCheckBox; // checkBox->setChecked(isChecked); // checkBox->setStyleSheet(R"( // QCheckBox::indicator { // width: 20px; // height: 20px; // } // QCheckBox::indicator:unchecked { // background-color: #FFFFFF; // border: 1px solid #BABBDC; // border-radius: 2px; // } // QCheckBox::indicator:checked { // image: url(:/images/three_Selecte.png); // } // QCheckBox { // spacing: 0px; // } // )"); // rightLayout->addWidget(checkBox); // createdWidget = checkBox; // connect(checkBox, &QCheckBox::stateChanged, [this,fieldTableName,fieldId](int state) { // if (state == Qt::Checked) { // // qDebug() << "CheckBox is checked"<setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); // comboBox->setFixedSize(140, 28); // comboBox->setStyleSheet(R"( // QComboBox { // background: #FFFFFF; // border: 1px solid #BABBDC; // border-radius: 6px; // padding: 2px 5px; // } // QComboBox::drop-down { // width: 20px; // } // )"); // // int newIndex = -1; // for (const QString &opt : optionList) { // QString trimmedOpt = opt.trimmed(); // if (!trimmedOpt.isEmpty()) // comboBox->addItem(trimmedOpt); // } // if(fieldValue == ""){ // comboBox->setCurrentIndex(0); // }else{ // comboBox->setCurrentIndex(fieldValue.toInt()); // } // rightLayout->addWidget(comboBox); // createdWidget = comboBox; // // 使用Lambda函数连接 currentIndexChanged 信号 // connect(comboBox, QOverload::of(&QComboBox::currentIndexChanged), [this,comboBox,fieldTableName,fieldId](int index) { // QString selectedText = comboBox->itemText(index); // QString indexString = QString::number(index); // // qDebug() << "ComboBox index changed to:" << index << "Text:" << selectedText; // updateDb(fieldTableName,fieldId,indexString); // // 在这里添加你想要执行的操作 // }); // } // else if (fieldType == "time") { // QTimeEdit *timeEdit = new QTimeEdit; // timeEdit->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); // timeEdit->setFixedSize(120, 28); // timeEdit->setStyleSheet(R"( // QTimeEdit { // background: #FFFFFF; // border: 1px solid #BABBDC; // border-radius: 6px; // padding: 2px 5px; // } // )"); // timeEdit->setDisplayFormat("HH:mm:ss"); // timeEdit->setTime(QTime::fromString(fieldValue, "HH:mm:ss")); // rightLayout->addWidget(timeEdit); // createdWidget = timeEdit; // } // else if (fieldType == "switch") { // QWidget *switchContainer = new QWidget; // QHBoxLayout *switchLayout = new QHBoxLayout(switchContainer); // switchLayout->setSpacing(5); // switchLayout->setContentsMargins(0, 0, 0, 0); // QCheckBox *switchBox = new QCheckBox; // switchBox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); // switchBox->setFixedSize(30, 30); // switchBox->setStyleSheet(R"( // QCheckBox::indicator { // width: 30px; // height: 30px; // } // QCheckBox::indicator:unchecked { // background-color: #BABBDC; // border-radius: 6px; // } // QCheckBox::indicator:checked { // background-color: #4CAF50; // border-radius: 6px; // } // )"); // QString switchValue; // // if(fieldValue ==""){ // switchValue = fieldValue.toLower(); // }else{ // switchValue = fieldValue.toLower(); // } // if (switchValue == "on") // switchBox->setChecked(true); // else // switchBox->setChecked(false); // QLabel *switchLabel = new QLabel(switchBox->isChecked() ? "开" : "关"); // switchLabel->setAlignment(Qt::AlignVCenter | Qt::AlignLeft); // switchLabel->setStyleSheet("font-size: 14px;"); // connect(switchBox, &QCheckBox::stateChanged, [fieldTableName,fieldId,switchLabel, this](int state){ // if (state == Qt::Checked){ // switchLabel->setText("开"); // updateDb(fieldTableName,fieldId,"on"); // }else{ // switchLabel->setText("关"); // updateDb(fieldTableName,fieldId,"off"); // } // }); // switchLayout->addWidget(switchBox); // switchLayout->addWidget(switchLabel); // rightLayout->addWidget(switchContainer); // createdWidget = switchBox; // } // else if (fieldType == "combined") { // // 用逗号分隔 // QStringList parts = fieldValue.split(QRegExp("[,,]"), Qt::SkipEmptyParts); // QString inputText = (parts.size() >= 1 ? parts.at(0).trimmed() : QString()); // QString button1Text = (parts.size() >= 2 ? parts.at(1).trimmed() : QStringLiteral("获取")); // QString button2Text = (parts.size() >= 3 ? parts.at(2).trimmed() : QStringLiteral("设置")); // // QLineEdit *comboInput = new QLineEdit(inputText); // comboInput->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); // comboInput->setFixedHeight(28); // comboInput->setStyleSheet(R"( // QLineEdit { // background: #FFFFFF; // border: 1px solid #BABBDC; // border-radius: 5px; // padding: 2px 5px; // } // )"); // m_fieldWidgets.append(comboInput); // // QWidget *combinedWidget = new QWidget; // QHBoxLayout *combinedLayout = new QHBoxLayout(combinedWidget); // combinedLayout->setSpacing(5); // combinedLayout->setContentsMargins(0, 0, 0, 0); // // QPushButton *btnGet = new QPushButton(button1Text, combinedWidget); // btnGet->setFixedSize(80, 28); // btnGet->setStyleSheet(R"( // QPushButton { // background: #FFFFFF; // border: 1px solid #BABBDC; // border-radius: 5px; // } // QPushButton:hover { // background-color: #F0F0F0; // } // )"); // m_fieldWidgets.append(btnGet); // // QPushButton *btnSet = new QPushButton(button2Text, combinedWidget); // btnSet->setFixedSize(80, 28); // btnSet->setStyleSheet(R"( // QPushButton { // background: #FFFFFF; // border: 1px solid #BABBDC; // border-radius: 5px; // } // QPushButton:hover { // background-color: #F0F0F0; // } // )"); // m_fieldWidgets.append(btnSet); // // combinedLayout->addWidget(comboInput); // combinedLayout->addWidget(btnGet); // combinedLayout->addWidget(btnSet); // combinedLayout->addStretch(); // rightLayout->addWidget(combinedWidget); // } // else if (fieldType == "Text") // { // QLabel* label = new QLabel(); // label->setText(fieldValue); // label->setAlignment(Qt::AlignVCenter | Qt::AlignLeft); // label->setFixedHeight(24); // label->setMinimumWidth(120); // rightLayout->addWidget(label); // // } else // { // qWarning() << "未知字段类型:" << fieldType; // } // // if (createdWidget) // m_fieldWidgets.append(createdWidget); // // fieldLayout->addWidget(rightWidget); // scrollLayout->addLayout(fieldLayout); // } // } // // scrollLayout->addStretch(); // // scrollArea->setWidget(scrollWidget); // // QVBoxLayout *mainLayout = new QVBoxLayout(m_thirdLevelFieldWnd); // mainLayout->setContentsMargins(0, 0, 0, 0); // mainLayout->addWidget(scrollArea); // // m_thirdLevelFieldWnd->show(); //} void DbTreeViewManager::displayThirdLevelFields(const QList& data, bool allChangeFlag, bool isHome) { if (data.isEmpty()) { qWarning() << "字段数据为空,无法显示"; return; } //遍历得到结果allChangeFalg // 若已有第三层窗口,先关闭并释放 if (m_thirdLevelFieldWnd) { m_thirdLevelFieldWnd->close(); m_thirdLevelFieldWnd->deleteLater(); m_thirdLevelFieldWnd = nullptr; } // 获取当前选中的目录项,设置状态 QModelIndex currentIndex = treeViewDown->currentIndex(); if (currentIndex.isValid()) { QStandardItem* currentItem = model->itemFromIndex(currentIndex); if (currentItem) { currentItem->setCheckState(allChangeFlag ? Qt::Checked : Qt::Unchecked); qDebug() << "设置当前目录项复选框状态为:" << (allChangeFlag ? "Checked" : "Unchecked"); } } else { qWarning() << "当前没有选中的目录项"; } // 隐藏目录树及所有分隔线 treeViewDown->hide(); for (auto separator : firstLevelSeparators) { if (separator) separator->hide(); } // 清理之前的控件列表 m_fieldWidgets.clear(); // 创建新的 "字段展示" 窗口,并赋值给 m_thirdLevelFieldWnd m_thirdLevelFieldWnd = new QWidget(widget2); m_thirdLevelFieldWnd->setWindowTitle("字段展示"); m_thirdLevelFieldWnd->setStyleSheet("background-color: transparent;"); if (isHome) { // Home 界面,填满 widget2 m_thirdLevelFieldWnd->setGeometry(0, 0, widget2->width(), widget2->height()); } else { // 其他配置界面,设置与 treeViewDown 相同的几何位置 m_thirdLevelFieldWnd->setGeometry(treeViewDown->geometry()); } // 创建滚动区域 QScrollArea* scrollArea = new QScrollArea(m_thirdLevelFieldWnd); scrollArea->setWidgetResizable(true); scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); // 创建滚动容器并设置布局 QWidget* scrollWidget = new QWidget; scrollWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); QVBoxLayout* scrollLayout = new QVBoxLayout(scrollWidget); scrollLayout->setSpacing(10); scrollLayout->setContentsMargins(10, 10, 10, 10); //不同表格的全部插进来 int previousGroupId = -1; QList buttonControls; for (const Table_Control_Data& tableData : data) { //遍历控件list for (const CONFIG_BASE_STRUCT& control : tableData.controlDataList) { //判断特殊的按钮控件 if (control.strType == "Button") { buttonControls.append(control); } else { //先创建label //int fieldId = control.iId; QString fieldName = QString::fromStdString(control.strName); QString fieldDescribe = QString::fromStdString(control.strDescribe); QString fieldType = QString::fromStdString(control.strType); QString fieldValue = QString::fromStdString(control.strValue); QString fieldUpLimit = QString::fromStdString(control.strUpperLimit); QString fieldDownLimit = QString::fromStdString(control.strLowerLimit); QString fieldUnits = QString::fromStdString(control.strUnit); int groupId = control.iGroupId; QString fieldTableName = tableData.tableName; // 如果组变化,插入分隔线 if (previousGroupId != -1 && groupId != previousGroupId) { QFrame* separator = createUnifiedSeparator(scrollWidget, 2); QHBoxLayout* separatorLayout = new QHBoxLayout; separatorLayout->setContentsMargins(0, 5, 0, 5); separatorLayout->addWidget(separator); scrollLayout->addLayout(separatorLayout); separator->show(); } previousGroupId = groupId; // 每个字段一行 QHBoxLayout* fieldLayout = new QHBoxLayout; fieldLayout->setSpacing(5); QLabel* label = new QLabel(fieldDescribe); label->setAlignment(Qt::AlignVCenter | Qt::AlignLeft); label->setFixedHeight(24); label->setMinimumWidth(120); fieldLayout->addWidget(label); fieldLayout->addStretch(1); QWidget* rightWidget = new QWidget; QHBoxLayout* rightLayout = new QHBoxLayout(rightWidget); rightLayout->setContentsMargins(0, 0, 20, 0); rightLayout->setSpacing(5); QWidget* createdWidget = nullptr; if (fieldType == "input" || fieldType == "POSITION" || fieldType == "LONG" || fieldType == "STRING") { // 检查 Value 中是否包含逗号分隔(比如 "请输入内容1,分钟") if (fieldUnits != "") { // // 采用逗号分割,trim去除空白 // QStringList parts = fieldValue.split(",", Qt::SkipEmptyParts); // QString leftText = parts.at(0).trimmed(); // QString rightText = (parts.size() > 1 ? parts.at(1).trimmed() : QString()); // 创建 QLineEdit 显示左边文本 QLineEdit* lineEdit = new QLineEdit(); if ((fieldUpLimit == "") && (fieldDownLimit == "")) { lineEdit->setText(fieldValue); lineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); lineEdit->setFixedSize(105, 28); lineEdit->setAlignment(Qt::AlignLeft); //!!!提到前面 lineEdit->setStyleSheet(R"( QLineEdit { background: #FFFFFF; border: 1px solid #BABBDC; border-radius: 6px; padding: 2px 5px; } )"); } else {//上下限至少设置了一个值 if (fieldValue == "") { lineEdit->setPlaceholderText("请输入数字"); } else { lineEdit->setText(fieldValue); } lineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); lineEdit->setFixedSize(105, 28); lineEdit->setAlignment(Qt::AlignLeft); lineEdit->setStyleSheet(R"( QLineEdit { background: #FFFFFF; border: 1px solid #BABBDC; border-radius: 6px; padding: 2px 5px; } )"); } // 创建 QLabel 显示右边文本(比如 "分钟") QLabel* unitLabel = new QLabel(fieldUnits); unitLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); unitLabel->setFixedHeight(28); unitLabel->setStyleSheet("QLabel { font-size: 14px; }"); // 把 QLineEdit 和 QLabel 水平排列,确保 Qlabel 显示在 QLineEdit 右侧 QHBoxLayout* inputLayout = new QHBoxLayout; inputLayout->setSpacing(10); inputLayout->setContentsMargins(0, 0, 0, 0); inputLayout->addWidget(lineEdit); inputLayout->addWidget(unitLabel); // 用一个容器部件来装下这个布局 QWidget* inputWidget = new QWidget; inputWidget->setLayout(inputLayout); rightLayout->addWidget(inputWidget); // 保存控件指针到 m_fieldWidgets(可选) m_fieldWidgets.append(lineEdit); m_fieldWidgets.append(unitLabel); createdWidget = inputWidget; // // 连接 textChanged 信号到 lambda 函数 connect(lineEdit, &QLineEdit::textChanged, [this, lineEdit, fieldTableName, fieldName, fieldUpLimit, fieldDownLimit]() { if ((fieldUpLimit != "") && (fieldDownLimit != "")) { int uplimit = fieldUpLimit.toInt(); int downlimit = fieldDownLimit.toInt(); int inputvalue = (lineEdit->text()).toInt(); if ((inputvalue <= uplimit) && (inputvalue >= downlimit)) { m_sqlOper->updateControlData(fieldTableName, fieldName, lineEdit->text()); //updateDb(fieldTableName, fieldId, lineEdit->text()); } else { lineEdit->setPlaceholderText("超出设定范围,请重新输入"); } } else if (fieldDownLimit != "") { int downlimit = fieldDownLimit.toInt(); int inputvalue = (lineEdit->text()).toInt(); if (inputvalue >= downlimit) { m_sqlOper->updateControlData(fieldTableName, fieldName, lineEdit->text()); //updateDb(fieldTableName, fieldId, lineEdit->text()); } else { lineEdit->setPlaceholderText("超出设定范围,请重新输入"); } } else if (fieldUpLimit != "") { int uplimit = fieldUpLimit.toInt(); int inputvalue = (lineEdit->text()).toInt(); if (inputvalue <= uplimit) { m_sqlOper->updateControlData(fieldTableName, fieldName, lineEdit->text()); //updateDb(fieldTableName, fieldId, lineEdit->text()); } else { lineEdit->setPlaceholderText("超出设定范围,请重新输入"); } } else { m_sqlOper->updateControlData(fieldTableName, fieldName, lineEdit->text()); //updateDb(fieldTableName, fieldId, lineEdit->text()); } }); } else { // 如果不包含逗号,按原有逻辑只创建 QLineEdit QLineEdit* lineEdit1 = new QLineEdit(fieldValue); lineEdit1->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); lineEdit1->setFixedSize(140, 28); lineEdit1->setAlignment(Qt::AlignLeft); lineEdit1->setStyleSheet(R"( QLineEdit { background: #FFFFFF; border: 1px solid #BABBDC; border-radius: 6px; padding: 2px 5px; } )"); rightLayout->addWidget(lineEdit1); createdWidget = lineEdit1; // // 连接 textChanged 信号到 lambda 函数 connect(lineEdit1, &QLineEdit::textChanged, [this, lineEdit1, fieldTableName, fieldName]() { m_sqlOper->updateControlData(fieldTableName, fieldName, lineEdit1->text()); //updateDb(fieldTableName, fieldId, lineEdit1->text()); loginput(fieldTableName, fieldName, lineEdit1->text()); }); } } else if (fieldType == "radio") { // 用逗号分隔的选项 QStringList optionList = fieldUnits.split(QRegExp("[,,]"), Qt::SkipEmptyParts); QHBoxLayout* radioLayout = new QHBoxLayout; radioLayout->setSpacing(5); QButtonGroup* radioGroup = new QButtonGroup(rightWidget); for (const QString& optionText : optionList) { QString trimmedOpt = optionText.trimmed(); if (trimmedOpt.isEmpty()) continue; QRadioButton* radioButton = new QRadioButton(trimmedOpt); radioGroup->addButton(radioButton); radioLayout->addWidget(radioButton); m_fieldWidgets.append(radioButton); if (fieldValue == trimmedOpt) { radioButton->setChecked(true); } } // 使用Lambda函数连接 buttonToggled 信号 connect(radioGroup, static_cast(&QButtonGroup::buttonToggled), [this, fieldTableName, fieldName](QAbstractButton* button, bool checked) { if (checked) { // qDebug() << "Button toggled:" << button->text(); // 在这里添加你想要执行的操作 m_sqlOper->updateControlData(fieldTableName, fieldName, button->text()); //updateDb(fieldTableName, fieldId, button->text()); } }); rightLayout->addLayout(radioLayout); } else if (fieldType == "checkbox" || fieldType == "BOOL") { bool isChecked; if (fieldValue == "") { isChecked = (fieldValue == "1"); } else { isChecked = (fieldValue == "1"); } QCheckBox* checkBox = new QCheckBox; checkBox->setChecked(isChecked); checkBox->setStyleSheet(R"( QCheckBox::indicator { width: 20px; height: 20px; } QCheckBox::indicator:unchecked { background-color: #FFFFFF; border: 1px solid #BABBDC; border-radius: 2px; } QCheckBox::indicator:checked { image: url(:/images/three_Selecte.png); } QCheckBox { spacing: 0px; } )"); rightLayout->addWidget(checkBox); createdWidget = checkBox; connect(checkBox, &QCheckBox::stateChanged, [this, fieldTableName, fieldName](int state) { if (state == Qt::Checked) { // qDebug() << "CheckBox is checked"<updateControlData(fieldTableName, fieldName, "1"); //updateDb(fieldTableName, fieldId, "1"); } else if (state == Qt::Unchecked) { // qDebug() << "CheckBox is unchecked"<updateControlData(fieldTableName, fieldName, "0"); //updateDb(fieldTableName, fieldId, "0"); } else if (state == Qt::PartiallyChecked) { qDebug() << "CheckBox is partially checked"; // 在这里添加你想要执行的操作 } }); } else if (fieldType == "ComboBox") { QStringList optionList = fieldValue.split(QRegExp("[,,]"), Qt::SkipEmptyParts); QComboBox* comboBox = new QComboBox; comboBox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); comboBox->setFixedSize(140, 28); comboBox->setStyleSheet(R"( QComboBox { background: #FFFFFF; border: 1px solid #BABBDC; border-radius: 6px; padding: 2px 5px; } QComboBox::drop-down { width: 20px; } )"); // int newIndex = -1; for (const QString& opt : optionList) { QString trimmedOpt = opt.trimmed(); if (!trimmedOpt.isEmpty()) comboBox->addItem(trimmedOpt); } if (fieldValue == "") { comboBox->setCurrentIndex(0); } else { comboBox->setCurrentIndex(fieldValue.toInt()); } rightLayout->addWidget(comboBox); createdWidget = comboBox; // 使用Lambda函数连接 currentIndexChanged 信号 connect(comboBox, QOverload::of(&QComboBox::currentIndexChanged), [this, comboBox, fieldTableName, fieldName](int index) { QString selectedText = comboBox->itemText(index); QString indexString = QString::number(index); // qDebug() << "ComboBox index changed to:" << index << "Text:" << selectedText; m_sqlOper->updateControlData(fieldTableName, fieldName, indexString); //updateDb(fieldTableName, fieldId, indexString); // 在这里添加你想要执行的操作 }); } else if (fieldType == "time") { QTimeEdit* timeEdit = new QTimeEdit; timeEdit->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); timeEdit->setFixedSize(120, 28); timeEdit->setStyleSheet(R"( QTimeEdit { background: #FFFFFF; border: 1px solid #BABBDC; border-radius: 6px; padding: 2px 5px; } )"); timeEdit->setDisplayFormat("HH:mm:ss"); timeEdit->setTime(QTime::fromString(fieldValue, "HH:mm:ss")); rightLayout->addWidget(timeEdit); createdWidget = timeEdit; } else if (fieldType == "switch") { QWidget* switchContainer = new QWidget; QHBoxLayout* switchLayout = new QHBoxLayout(switchContainer); switchLayout->setSpacing(5); switchLayout->setContentsMargins(0, 0, 0, 0); QCheckBox* switchBox = new QCheckBox; switchBox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); switchBox->setFixedSize(30, 30); switchBox->setStyleSheet(R"( QCheckBox::indicator { width: 30px; height: 30px; } QCheckBox::indicator:unchecked { background-color: #BABBDC; border-radius: 6px; } QCheckBox::indicator:checked { background-color: #4CAF50; border-radius: 6px; } )"); QString switchValue; if (fieldValue == "") { switchValue = fieldValue.toLower(); } else { switchValue = fieldValue.toLower(); } if (switchValue == "on") switchBox->setChecked(true); else switchBox->setChecked(false); QLabel* switchLabel = new QLabel(switchBox->isChecked() ? "开" : "关"); switchLabel->setAlignment(Qt::AlignVCenter | Qt::AlignLeft); switchLabel->setStyleSheet("font-size: 14px;"); connect(switchBox, &QCheckBox::stateChanged, [fieldTableName, fieldName, switchLabel, this](int state) { if (state == Qt::Checked) { switchLabel->setText("开"); m_sqlOper->updateControlData(fieldTableName, fieldName, "on"); //updateDb(fieldTableName, fieldId, "on"); } else { switchLabel->setText("关"); m_sqlOper->updateControlData(fieldTableName, fieldName, "off"); //updateDb(fieldTableName, fieldId, "off"); } }); switchLayout->addWidget(switchBox); switchLayout->addWidget(switchLabel); rightLayout->addWidget(switchContainer); createdWidget = switchBox; } else if (fieldType == "combined") { // 用逗号分隔 QStringList parts = fieldValue.split(QRegExp("[,,]"), Qt::SkipEmptyParts); QString inputText = (parts.size() >= 1 ? parts.at(0).trimmed() : QString()); QString button1Text = (parts.size() >= 2 ? parts.at(1).trimmed() : QStringLiteral("获取")); QString button2Text = (parts.size() >= 3 ? parts.at(2).trimmed() : QStringLiteral("设置")); QLineEdit* comboInput = new QLineEdit(inputText); comboInput->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); comboInput->setFixedHeight(28); comboInput->setStyleSheet(R"( QLineEdit { background: #FFFFFF; border: 1px solid #BABBDC; border-radius: 5px; padding: 2px 5px; } )"); m_fieldWidgets.append(comboInput); QWidget* combinedWidget = new QWidget; QHBoxLayout* combinedLayout = new QHBoxLayout(combinedWidget); combinedLayout->setSpacing(5); combinedLayout->setContentsMargins(0, 0, 0, 0); QPushButton* btnGet = new QPushButton(button1Text, combinedWidget); btnGet->setFixedSize(80, 28); btnGet->setStyleSheet(R"( QPushButton { background: #FFFFFF; border: 1px solid #BABBDC; border-radius: 5px; } QPushButton:hover { background-color: #F0F0F0; } )"); m_fieldWidgets.append(btnGet); QPushButton* btnSet = new QPushButton(button2Text, combinedWidget); btnSet->setFixedSize(80, 28); btnSet->setStyleSheet(R"( QPushButton { background: #FFFFFF; border: 1px solid #BABBDC; border-radius: 5px; } QPushButton:hover { background-color: #F0F0F0; } )"); m_fieldWidgets.append(btnSet); combinedLayout->addWidget(comboInput); combinedLayout->addWidget(btnGet); combinedLayout->addWidget(btnSet); combinedLayout->addStretch(); rightLayout->addWidget(combinedWidget); } else if (fieldType == "Text") { QLabel* label = new QLabel(); label->setText(fieldValue); label->setAlignment(Qt::AlignVCenter | Qt::AlignLeft); label->setFixedHeight(24); label->setMinimumWidth(120); rightLayout->addWidget(label); } else { qWarning() << "未知字段类型:" << fieldType; } if (createdWidget) m_fieldWidgets.append(createdWidget); fieldLayout->addWidget(rightWidget); scrollLayout->addLayout(fieldLayout); } } } scrollLayout->addStretch(); scrollArea->setWidget(scrollWidget); QVBoxLayout* mainLayout = new QVBoxLayout(m_thirdLevelFieldWnd); mainLayout->setContentsMargins(0, 0, 0, 0); mainLayout->addWidget(scrollArea); m_thirdLevelFieldWnd->show(); // 显示按钮 displayThirdLevelButtons(buttonControls); //loadButtonConfigForThirdLevel(data); } void DbTreeViewManager::updateParentCheckState(QStandardItem *item) { if (!item) return; QStandardItem *parentItem = item->parent(); if (!parentItem) return; bool allChecked = true; bool noneChecked = true; for (int i = 0; i < parentItem->rowCount(); ++i) { QStandardItem *child = parentItem->child(i); if (child->checkState() != Qt::Checked) { allChecked = false; } if (child->checkState() == Qt::Checked) { noneChecked = false; } } if (allChecked) { parentItem->setCheckState(Qt::Checked); } else { parentItem->setCheckState(Qt::Unchecked); } if (noneChecked) { qDebug() << "noneChecked状态为:" << noneChecked; } // 递归更新上一级 updateParentCheckState(parentItem); } void DbTreeViewManager::onButtonBackClicked() { if (m_thirdLevelFieldWnd) { // 当前在第三层目录,返回到上一层目录 qDebug() << "当前在第三层目录,准备返回上一层。"; for(int i=0;i<5;i++){ if(currentMenuId == menuArray[i].menuId){ menuArray[i].isthird = false; } } // 关闭并销毁字段展示窗口 m_thirdLevelFieldWnd->close(); m_thirdLevelFieldWnd->deleteLater(); m_thirdLevelFieldWnd = nullptr; // 显示目录树和分隔线 treeViewDown->show(); for (auto separator : firstLevelSeparators) { if (separator) separator->show(); } // 获取当前导航路径 QStringList path; QLayout* layout = navigationWidget->layout(); if (!layout) { qWarning() << "导航栏没有布局,无法获取路径。"; return; } for (int i = 0; i < layout->count(); ++i) { QLayoutItem* item = layout->itemAt(i); if (item && item->widget()) { QLabel* label = qobject_cast(item->widget()); if (label) { QString text = label->text().trimmed(); if (!text.isEmpty()) { path << text; } } } } if (path.isEmpty()) { qWarning() << "导航路径为空,无法返回上一层。"; return; } // 移除最后一个目录名称以返回上一层 path.removeLast(); if (path.isEmpty()) { qDebug() << "已经在根目录,无法返回。"; return; } // 根据新的路径查找对应的 QModelIndex QModelIndex parentIndex = findItemByPath(path); if (!parentIndex.isValid()) { qWarning() << "无法找到路径对应的目录项:" << path; return; } // 选中父目录项 treeViewDown->setCurrentIndex(parentIndex); treeViewDown->scrollTo(parentIndex); // 更新导航栏 updateNavigationBar(parentIndex); // 检查父目录是否为第三层目录 QStandardItem* parentItem = model->itemFromIndex(parentIndex); if (!parentItem) { qWarning() << "父目录项无效。"; return; } QVariant dataVar = parentItem->data(Qt::UserRole + 2); bool isThirdLevel = false; int directoryId = -1; QString multiTableName = ""; if (dataVar.canConvert()) { QJsonObject dataObj = dataVar.toJsonObject(); if (dataObj.contains("IsThirdLevel") && dataObj["IsThirdLevel"].toBool()) { isThirdLevel = true; if (dataObj.contains("Id")) { directoryId = dataObj["Id"].toInt(); } if (dataObj.contains("TableName")) { multiTableName = dataObj["TableName"].toString(); } } } if (isThirdLevel) { if (directoryId == -1) { qWarning() << "无效的 DirectoryId,无法加载第三层目录内容。"; return; } int userPrivilege = 0x1; // 当前用户的权限等级 QList tableControlDatas; bool allChangeFlag = false; m_sqlOper->GetThirdDirControlData(multiTableName, userPrivilege, tableControlDatas, allChangeFlag); displayThirdLevelFields(tableControlDatas, allChangeFlag, false); // 传递参数表示 Home 界面 // 获取第三层目录的数据 //m_sqlOper->GetThirdDirControlData(); //QJsonObject data = fetchThirdLevelData(directoryId, userPrivilege); // 显示字段展示窗口 //displayThirdLevelFields(data, false); // 传递参数表示非 Home 界面 } else { // 父目录不是第三层目录,确保目录树和分隔线可见 treeViewDown->show(); for (auto separator : firstLevelSeparators) { if (separator) separator->show(); } } return; } // 如果不在第三层目录,则在目录树中返回上一层 qDebug() << "当前不在第三层目录,尝试在目录树中返回上一层。"; QModelIndex currentIndex = treeViewDown->currentIndex(); if (!currentIndex.isValid()) { qWarning() << "当前没有选中的目录项,无法返回。"; return; } QStandardItem* currentItem = model->itemFromIndex(currentIndex); if (!currentItem) { qWarning() << "当前选中的目录项无效。"; return; } QStandardItem* parentItem = currentItem->parent(); if (!parentItem) { qDebug() << "当前已经在根目录,无法返回。"; return; } QModelIndex parentIndex = model->indexFromItem(parentItem); if (!parentIndex.isValid()) { qWarning() << "父目录的 QModelIndex 无效。"; return; } // 选中父目录项 treeViewDown->setCurrentIndex(parentIndex); treeViewDown->scrollTo(parentIndex); // 更新导航栏 updateNavigationBar(parentIndex); // 检查父目录是否为第三层目录 QVariant dataVar = parentItem->data(Qt::UserRole + 2); bool isThirdLevel = false; int directoryId = -1; QString multiTableName = ""; if (dataVar.canConvert()) { QJsonObject dataObj = dataVar.toJsonObject(); if (dataObj.contains("IsThirdLevel") && dataObj["IsThirdLevel"].toBool()) { isThirdLevel = true; if (dataObj.contains("Id")) { directoryId = dataObj["Id"].toInt(); } if (dataObj.contains("TableName")) { multiTableName = dataObj["TableName"].toString(); } } } if (isThirdLevel) { if (directoryId == -1) { qWarning() << "无效的 DirectoryId,无法加载第三层目录内容。"; return; } int userPrivilege = 0x1; // 根据实际情况获取当前用户的权限等级 QList tableControlDatas; bool allChangeFlag = false; m_sqlOper->GetThirdDirControlData(multiTableName, userPrivilege, tableControlDatas, allChangeFlag); displayThirdLevelFields(tableControlDatas, allChangeFlag, false); // 传递参数表示 Home 界面 //QJsonObject data = fetchThirdLevelData(directoryId, userPrivilege); //displayThirdLevelFields(data, false); // 传递参数表示非 Home 界面 } } QList DbTreeViewManager::collectAllThirdLevelItems() { QList result; // 从根节点开始递归搜集 QStandardItem *root = model->invisibleRootItem(); if (!root) return result; std::function dfsCollectThirdLevel; dfsCollectThirdLevel = [&](QStandardItem* parentItem) { if (!parentItem) return; int rowCount = parentItem->rowCount(); for (int i = 0; i < rowCount; ++i) { QStandardItem *child = parentItem->child(i); if (!child) continue; // 判断是否是第三层 QVariant dataVar = child->data(Qt::UserRole + 2); if (dataVar.canConvert()) { QJsonObject obj = dataVar.toJsonObject(); if (obj.contains("IsThirdLevel") && obj["IsThirdLevel"].toBool()) { // 收集这个第三层节点 result.append(child); } } // 即使不是第三层,也要继续往下找子节点 dfsCollectThirdLevel(child); } }; dfsCollectThirdLevel(root); return result; } void DbTreeViewManager::onButtonDownClicked() { // 1) 收集所有 第三层 节点 QList thirdLevelList = collectAllThirdLevelItems(); if (thirdLevelList.isEmpty()) { qDebug() << "[onButtonDownClicked] 没有任何三级目录,无法遍历。"; return; } // 2) 找到 当前选中的节点 在 thirdLevelList 里的索引 QModelIndex curIndex = treeViewDown->currentIndex(); if (!curIndex.isValid()) { qDebug() << "[onButtonDownClicked] 当前没有选中节点,默认跳到第一个三级目录。"; // 如果想默认跳到第一个 QStandardItem *firstItem = thirdLevelList.first(); QModelIndex idx = model->indexFromItem(firstItem); treeViewDown->setCurrentIndex(idx); // 模拟点击一下 onTreeViewClicked_updown(idx); // 保存复选框状态 saveCheckedPaths(); // 保存展开路径 saveExpandedPaths(); return; } QStandardItem *curItem = model->itemFromIndex(curIndex); if (!curItem) { qWarning() << "[onButtonDownClicked] currentItem 无效。"; return; } // 若不是三级目录,就先找它最近的父级是不是三级目录,否则当做没找到。 int currentPos = -1; { // 在 thirdLevelList 里找到 curItem currentPos = thirdLevelList.indexOf(curItem); if (currentPos < 0) { qDebug() << "[onButtonDownClicked] 当前节点不是三级目录,尝试找父级是不是三级目录…"; // 向上找父节点是否在 thirdLevelList 里 QStandardItem *temp = curItem->parent(); while (temp) { int pos = thirdLevelList.indexOf(temp); if (pos >= 0) { currentPos = pos; break; } temp = temp->parent(); } if (currentPos < 0) { qDebug() << "还是找不到,说明当前目录不属于任何三级目录,直接跳到第一个"; QStandardItem *firstItem = thirdLevelList.first(); QModelIndex idx = model->indexFromItem(firstItem); treeViewDown->setCurrentIndex(idx); onTreeViewClicked_updown(idx); // 保存复选框状态 saveCheckedPaths(); // 保存展开路径 saveExpandedPaths(); return; } } } // 尝试下一个 int nextPos = currentPos + 1; if (nextPos >= thirdLevelList.size()) { qDebug() << "[onButtonDownClicked] 已经是最后一个三级目录了,无法再向下。"; return; } // 跳到下一个 QStandardItem *nextItem = thirdLevelList[nextPos]; QModelIndex nextIndex = model->indexFromItem(nextItem); treeViewDown->setCurrentIndex(nextIndex); // 相当于模拟点击 onTreeViewClicked_updown(nextIndex); // 保存复选框状态 saveCheckedPaths(); // 保存展开路径 saveExpandedPaths(); } void DbTreeViewManager::onButtonUpClicked() { // 1) 收集所有 第三层 节点 QList thirdLevelList = collectAllThirdLevelItems(); if (thirdLevelList.isEmpty()) { qDebug() << "[onButtonUpClicked] 没有任何三级目录,无法遍历。"; return; } // 2) 找到 当前选中的节点 QModelIndex curIndex = treeViewDown->currentIndex(); if (!curIndex.isValid()) { qDebug() << "[onButtonUpClicked] 当前无选中节点,默认跳到最后一个三级目录。"; // 跳到最后一个 QStandardItem *lastItem = thirdLevelList.last(); QModelIndex idx = model->indexFromItem(lastItem); treeViewDown->setCurrentIndex(idx); // 模拟点击 onTreeViewClicked_updown(idx); // 保存复选框状态 saveCheckedPaths(); // 保存展开路径 saveExpandedPaths(); return; } QStandardItem *curItem = model->itemFromIndex(curIndex); if (!curItem) { qWarning() << "[onButtonUpClicked] currentItem 无效。"; return; } // 如果当前节点不是三级目录, 向上查找 int currentPos = thirdLevelList.indexOf(curItem); if (currentPos < 0) { qDebug() << "[onButtonUpClicked] 当前节点不是三级目录,尝试找父级是不是三级目录。"; QStandardItem *temp = curItem->parent(); while (temp) { int pos = thirdLevelList.indexOf(temp); if (pos >= 0) { currentPos = pos; break; } temp = temp->parent(); } if (currentPos < 0) { qDebug() << "找不到任何三级目录,直接跳到最后一个。"; QStandardItem *lastItem = thirdLevelList.last(); QModelIndex idx = model->indexFromItem(lastItem); treeViewDown->setCurrentIndex(idx); onTreeViewClicked_updown(idx); // 保存复选框状态 saveCheckedPaths(); // 保存展开路径 saveExpandedPaths(); return; } } // 尝试上一个 int prevPos = currentPos - 1; if (prevPos < 0) { qDebug() << "[onButtonUpClicked] 已经是第一个三级目录了,无法再向上。"; return; } // 跳到上一个 QStandardItem *prevItem = thirdLevelList[prevPos]; QModelIndex prevIndex = model->indexFromItem(prevItem); treeViewDown->setCurrentIndex(prevIndex); // 模拟点击 onTreeViewClicked_updown(prevIndex); // 保存复选框状态 saveCheckedPaths(); // 保存展开路径 saveExpandedPaths(); } void DbTreeViewManager::onButtonRightClicked() { if (m_forwardStack.isEmpty()) { qDebug() << "[Forward] 已经没有可以前进的页面"; buttonRight->setIcon(QIcon(":/images/home_right.png")); return; } // 1. 弹出 forwardStack 的最后一个 PageState st = m_forwardStack.takeLast(); // 2. 把当前页面 push 到 backStack PageState cur = getCurrentPageState(); m_backStack.append(cur); if(m_backStack.size() >= 2){ buttonLeft->setIcon(QIcon(":/images/home_left.png")); } // 3. 加载 st loadPageState(st, true); } void DbTreeViewManager::onButtonLeftClicked() { if (m_backStack.size() < 2) { qDebug() << "[Back] 已经无法再后退"; buttonLeft->setIcon(QIcon(":/images/home_left_hide.png")); return; } // 1. 先把当前页面(相当于 m_backStack 最后一个)弹出,放到 forwardStack PageState cur = m_backStack.takeLast(); if(m_backStack.size() >= 2){ buttonLeft->setIcon(QIcon(":/images/home_left.png")); }else{ buttonLeft->setIcon(QIcon(":/images/home_left_hide.png")); } m_forwardStack.append(cur); buttonRight->setIcon(QIcon(":/images/home_right_show.png")); // 2. 拿到新的 m_backStack 末尾(即上一次看的页面) const PageState &prev = m_backStack.last(); // 3. 加载 prev loadPageState(prev, true ); } // 构建节点的完整路径 QStringList DbTreeViewManager::buildItemPath(QStandardItem *item) { QStringList path; QStandardItem *currentItem = item; while (currentItem) { path.prepend(currentItem->text()); currentItem = currentItem->parent(); } return path; } // 根据路径查找对应的节点 QModelIndex DbTreeViewManager::findItemByPath(const QStringList &path) { if (path.isEmpty()) return QModelIndex(); QStandardItem *currentItem = model->invisibleRootItem(); QModelIndex currentIndex; for (const QString &part : path) { bool found = false; for (int i = 0; i < currentItem->rowCount(); ++i) { QStandardItem *child = currentItem->child(i); if (child == nullptr) { qDebug() << "child is nullptr"; } if (child->text() == part) { currentIndex = model->indexFromItem(child); currentItem = child; found = true; qDebug() << "找到路径部分:" << part; break; } } if (!found) { qWarning() << "路径部分未找到:" << part; return QModelIndex(); } } return currentIndex; } void DbTreeViewManager::setCheckedPaths(const QStringList &checkedPathsList) { m_blockItemChanged = true; for (const QString &pathStr : checkedPathsList) { QStringList path = pathStr.split("/"); QModelIndex idx = findItemByPath(path); if (idx.isValid()) { QStandardItem *item = model->itemFromIndex(idx); if (item) { item->setCheckState(Qt::Checked); qDebug() << " Setting item:" << item->text() << "to Checked"; } } else { qDebug() << "Path not found:" << pathStr; } } m_blockItemChanged = false; } // 递归收集被选中的路径 QStringList DbTreeViewManager::collectCheckedPathsRecursive(QStandardItem *item, QStringList path) { QStringList checkedList; if (!item) { item = model->invisibleRootItem(); } for (int i = 0; i < item->rowCount(); ++i) { QStandardItem *child = item->child(i); if (child) { QStringList currentPath = path; currentPath << child->text(); if (child->checkState() == Qt::Checked) { checkedList << currentPath.join("/"); } // 递归收集子项 checkedList << collectCheckedPathsRecursive(child, currentPath); } } return checkedList; } // 收集所有被选中的复选框路径 QStringList DbTreeViewManager::collectCheckedPaths() { return collectCheckedPathsRecursive(model->invisibleRootItem(), QStringList()); } // 更新父项的复选框状态 void DbTreeViewManager::updateParentItems(QStandardItem *parentItem) { if (!parentItem) return; int checkedCount = 0; int totalCount = parentItem->rowCount(); qDebug() << "Updating child items of:" << parentItem->text(); for (int i = 0; i < totalCount; ++i) { QStandardItem *child = parentItem->child(i); if (child && child->checkState() == Qt::Checked) { checkedCount++; } } if (checkedCount == totalCount) { parentItem->setCheckState(Qt::Checked); } else { parentItem->setCheckState(Qt::Unchecked); } // 递归更新上层父项 updateParentItems(parentItem->parent()); } // 加载并显示三级目录对应按钮配置信息 //void DbTreeViewManager::loadButtonConfigForThirdLevel(const QJsonObject &thirdLevelObj) //{ // if (!m_originalWnd) { // qWarning() << "OriginalWnd 指针为空,无法加载按钮配置"; // return; // } // // if (!thirdLevelObj.contains("buttons")) { // qWarning() << "三级目录配置中不包含 'buttons' 字段"; // return; // } // // QJsonArray buttonsArray = thirdLevelObj.value("buttons").toArray(); // // // 获取 widget_left // QWidget* widgetLeft = m_originalWnd->getWidgetLeft(); // if (!widgetLeft) { // qWarning() << "无法访问 widget_left"; // return; // } // // // 清空 widget_left 中由 loadButtonConfigForThirdLevel 创建的按钮 // QList existingButtons = widgetLeft->findChildren(); // for (QPushButton* button : existingButtons) { // if (button->objectName().startsWith("thirdLevelBtn_")) { // 仅删除特定按钮 // button->deleteLater(); // } // } // // // 使用绝对定位创建按钮 // for (int i = 0; i < buttonsArray.size() && i < 12; ++i) { // QJsonObject buttonObj = buttonsArray[i].toObject(); // QString buttonId = buttonObj.value("id").toString(); // QString buttonIcon = buttonObj.value("icon").toString(); // QString buttonText = buttonObj.value("text").toString(); // bool isEnabled = buttonObj.value("enabled").toBool(); // // // 创建按钮 // QPushButton *button = new QPushButton(widgetLeft); // button->setObjectName("thirdLevelBtn_" + buttonId); // 设置带前缀的对象名称 // connect(button, &QPushButton::clicked, this, []() { // JMessageTip::Message_question("Q111"); // }); // // // 设置按钮的样式,调整图标和文本的位置 // button->setStyleSheet(R"( // QPushButton { // position: absolute; // border-radius: 6px; // opacity: 1; // background: #CBD0FF; // border: none; // } // QPushButton:hover { // background-color: #A9B4FF; /* 鼠标悬停效果 */ // } // )"); // // // 设置按钮的位置和大小 // int x = 16; // int y = 245 + i * (48 + 13); // 第一个按钮 y=245,后续每个按钮间隔13px // button->setGeometry(x, y, 158, 48); // // // 设置按钮的可见性,根据 "enabled" 字段显示或隐藏按钮 // button->setVisible(isEnabled); // // // 创建图标标签 // QLabel *iconLabel = new QLabel(button); // iconLabel->setPixmap(QIcon(buttonIcon).pixmap(16, 16)); // iconLabel->setGeometry(10, 16, 16, 16); // 图标距离左边10px,顶部16px // iconLabel->setFixedSize(16, 16); // iconLabel->setStyleSheet("background-color: transparent;"); // iconLabel->setVisible(isEnabled); // 根据按钮的可见性设置图标的可见性 // // // 创建文本标签 // QLabel *textLabel = new QLabel(buttonText, button); // textLabel->setGeometry(34, 0, 90, 48); // 文本距离左边34px // textLabel->setWordWrap(true); // 允许换行 // textLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); // textLabel->setStyleSheet(R"( // QLabel { // background: transparent; // font-family: "思源黑体"; // font-size: 14px; // font-weight: 500; // color: #4E51CE; // } // )"); // // textLabel->setVisible(isEnabled); // 根据按钮的可见性设置文本的可见性 // // // 创建 F1-F12 标签 // QString fLabelText = QString("F%1").arg(i + 1); // F1, F2, ..., F12 // QLabel *fLabel = new QLabel(fLabelText, button); // fLabel->setFixedSize(21, 16); // 设置大小为21x16 // fLabel->setAlignment(Qt::AlignCenter); // fLabel->setStyleSheet(R"( // QLabel { // background-color: transparent; // color: #2A7ED8; // font-size: 12px; // font-weight: bold; // } // )"); // // // 设置标签的位置 // int fX = 134; // int fY = 2; // fLabel->setGeometry(fX, fY, 14, 16); // fLabel->setVisible(isEnabled); // 根据按钮的可见性设置标签的可见性 // // // 将按钮、图标、文本和标签添加到控件列表 // m_fieldWidgets.append(button); // m_fieldWidgets.append(iconLabel); // m_fieldWidgets.append(textLabel); // m_fieldWidgets.append(fLabel); // } //} void DbTreeViewManager::displayThirdLevelButtons(const QList& buttons) { if (!m_originalWnd) { qWarning() << "OriginalWnd 指针为空,无法加载按钮配置"; return; } // 获取 widget_left QWidget* widgetLeft = m_originalWnd->getWidgetLeft(); if (!widgetLeft) { qWarning() << "无法访问 widget_left"; return; } // 清空 widget_left 中由 loadButtonConfigForThirdLevel 创建的按钮 QList existingButtons = widgetLeft->findChildren(); for (QPushButton* button : existingButtons) { QString objName = button->objectName(); if (button->objectName().startsWith("thirdLevelBtn_F")) { // 仅删除特定按钮 button->deleteLater(); } } // 使用绝对定位创建按钮 for (int i = 0; i < buttons.size() && i < 12; ++i) { int buttonId = buttons[i].iGroupId; QString buttonIcon = QString::fromStdString(buttons[i].sIcon); QString buttonText = QString::fromStdString(buttons[i].strName); QString strCallFun = QString::fromStdString(buttons[i].strCallFun); bool isEnabled = buttons[i].bEnable; //for (int i = 0; i < buttonsArray.size() && i < 12; ++i) { //QJsonObject buttonObj = buttonsArray[i].toObject(); //QString buttonId = buttonObj.value("id").toString(); //QString strNumID = buttonId; // 不改变原来的意思 //strNumID.remove('F'); //QString strDirectoryId = buttonObj.value("DirectoryId").toString(); //QString buttonIcon = buttonObj.value("icon").toString(); //QString buttonText = buttonObj.value("text").toString(); //QString strCallFun = buttonObj.value("CallFun").toString(); //bool isEnabled = buttonObj.value("enabled").toBool(); // 创建按钮 QPushButton *button = new QPushButton(widgetLeft); QString ObjectName = "thirdLevelBtn_F" + QString::number(buttonId); button->setObjectName(ObjectName); // 设置带前缀的对象名称 ObjectName = button->objectName(); connect(button, &QPushButton::clicked, this, [&, strCallFun, buttonId]() { ns_module::ST_BUTTON_FUN callFun = {}; //callFun.DirectoryId = strDirectoryId.toInt(); callFun.strCallFun = strCallFun.toStdString(); callFun.nId = buttonId; emit RunFunSignals(callFun); }); // 设置按钮的样式,调整图标和文本的位置 button->setStyleSheet(R"( QPushButton { position: absolute; border-radius: 6px; opacity: 1; background: #CBD0FF; border: none; } QPushButton:hover { background-color: #A9B4FF; /* 鼠标悬停效果 */ } )"); if (buttonId > 12) { qWarning() << "buttonId 超过最大ID"; continue; } // 设置按钮的位置和大小 int x = 16; int y = 245 + (buttonId - 1) * (48 + 13); // 第一个按钮 y=245,后续每个按钮间隔13px button->setGeometry(x, y, 158, 48); // 设置按钮的可见性,根据 "enabled" 字段显示或隐藏按钮 button->setVisible(isEnabled); // 创建图标标签 QLabel* iconLabel = new QLabel(button); iconLabel->setPixmap(QIcon(buttonIcon).pixmap(16, 16)); iconLabel->setGeometry(10, 16, 16, 16); // 图标距离左边10px,顶部16px iconLabel->setFixedSize(16, 16); iconLabel->setStyleSheet("background-color: transparent;"); iconLabel->setVisible(isEnabled); // 根据按钮的可见性设置图标的可见性 // 创建文本标签 QLabel* textLabel = new QLabel(buttonText, button); textLabel->setGeometry(34, 0, 90, 48); // 文本距离左边34px textLabel->setWordWrap(true); // 允许换行 textLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); textLabel->setStyleSheet(R"( QLabel { background: transparent; font-family: "思源黑体"; font-size: 14px; font-weight: 500; color: #4E51CE; } )"); textLabel->setVisible(isEnabled); // 根据按钮的可见性设置文本的可见性 // 创建 F1-F12 标签 QString fLabelText = QString("F%1").arg(buttonId); // F1, F2, ..., F12 QLabel* fLabel = new QLabel(fLabelText, button); fLabel->setFixedSize(21, 16); // 设置大小为21x16 fLabel->setAlignment(Qt::AlignCenter); fLabel->setStyleSheet(R"( QLabel { background-color: transparent; color: #2A7ED8; font-size: 12px; font-weight: bold; } )"); // 设置标签的位置 int fX = 134; int fY = 2; fLabel->setGeometry(fX, fY, 14, 16); fLabel->setVisible(isEnabled); // 根据按钮的可见性设置标签的可见性 // 将按钮、图标、文本和标签添加到控件列表 m_fieldWidgets.append(button); m_fieldWidgets.append(iconLabel); m_fieldWidgets.append(textLabel); m_fieldWidgets.append(fLabel); } } // 清理并隐藏三级目录菜单内容 void DbTreeViewManager::clearThirdLevelMenu() { // 遍历所有子控件,找到标题为 "字段展示" 的窗口并关闭 foreach (QObject *child, widget2->children()) { QWidget *childWidget = qobject_cast(child); if (childWidget && childWidget->windowTitle() == "字段展示") { qDebug() << "关闭现有的字段展示窗口"; childWidget->close(); } } // 显示主目录树和分隔线 treeViewDown->show(); for (auto separator : firstLevelSeparators) { separator->show(); } } // 保存选中路径 void DbTreeViewManager::saveCheckedPaths() { if (m_currentConfigName == "") { qWarning() << "当前配置ID无效,无法保存复选框状态。"; return; } QSettings settings("RunCloudTech", "David"); //QString configKey = QString::number(m_currentConfigId); settings.beginGroup("TreeViewCheckedState"); // 保存选中路径 QString keyChecked = QString("checkedPaths/%1").arg(m_currentConfigName); QStringList checkedList = collectCheckedPaths(); settings.setValue(keyChecked, checkedList); settings.endGroup(); qDebug() << "保存复选框状态路径:" << checkedList; } // 加载选中路径 void DbTreeViewManager::loadCheckedPaths() { if (m_currentConfigName == "") { qWarning() << "当前配置ID无效,无法加载复选框状态。"; return; } QSettings settings("RunCloudTech", "David"); //QString configKey = QString::number(m_currentConfigId); settings.beginGroup("TreeViewCheckedState"); // 读取选中路径 QString keyChecked = QString("checkedPaths/%1").arg(m_currentConfigName); QStringList loadedChecked = settings.value(keyChecked).toStringList(); settings.endGroup(); qDebug() << "加载复选框状态路径:" << loadedChecked; m_blockItemChanged = true; setCheckedPaths(loadedChecked); m_blockItemChanged = false; // 更新导航栏 if (!loadedChecked.isEmpty()) { QString lastPathStr = loadedChecked.last(); QStringList lastPath = lastPathStr.split("/"); QModelIndex lastIdx = findItemByPath(lastPath); if (lastIdx.isValid()) { treeViewDown->setCurrentIndex(lastIdx); updateNavigationBar(lastIdx); } } else { // 如果没有加载到任何路径,自动选择第一个目录 QStandardItem *rootItem = model->invisibleRootItem(); if (rootItem->rowCount() > 0) { QModelIndex firstIndex = model->index(0, 0, QModelIndex()); if (firstIndex.isValid()) { treeViewDown->setCurrentIndex(firstIndex); treeViewDown->expand(firstIndex); // 展开第一个目录 QStandardItem *firstItem = model->itemFromIndex(firstIndex); QVariant data = firstItem->data(Qt::UserRole + 2); if (data.canConvert()) { QJsonObject thirdLevelObj = data.toJsonObject(); if (thirdLevelObj.contains("IsThirdLevel") && thirdLevelObj["IsThirdLevel"].toBool()) { QString multiTableName = ""; if (thirdLevelObj.contains("TableName")) { multiTableName = thirdLevelObj["TableName"].toString(); } QList buttons; int userGrade = 0x1; m_sqlOper->GetThirdDirButtons(multiTableName, userGrade, buttons); displayThirdLevelButtons(buttons); //loadButtonConfigForThirdLevel(thirdLevelObj); } } } } } } // 保存展开路径 void DbTreeViewManager::saveExpandedPaths() { if (m_currentConfigName == "") { qWarning() << "当前配置ID无效,无法保存展开路径。"; return; } QSettings settings("RunCloudTech", "David"); //QString configKey = QString::number(m_currentConfigId); settings.beginGroup("TreeViewExpandedState"); // 保存展开路径 QString keyExpanded = QString("expandedPaths/%1").arg(m_currentConfigName); QStringList expandedList = QStringList(expandedPaths.begin(), expandedPaths.end()); settings.setValue(keyExpanded, expandedList); settings.endGroup(); qDebug() << "保存展开路径:" << expandedList; } // 加载展开路径 void DbTreeViewManager::loadExpandedPaths() { if (m_currentConfigName == "") { qWarning() << "当前配置ID无效,无法加载展开路径。"; return; } QSettings settings("RunCloudTech", "David"); //QString configKey = QString::number(m_currentConfigId); settings.beginGroup("TreeViewExpandedState"); // 读取展开路径 QString keyExpanded = QString("expandedPaths/%1").arg(m_currentConfigName); QStringList loadedExpanded = settings.value(keyExpanded).toStringList(); settings.endGroup(); qDebug() << "加载展开路径:" << loadedExpanded; m_blockItemChanged = true; // 恢复展开路径 for (const QString &p : loadedExpanded) { QStringList path = p.split("/"); QModelIndex idx = findItemByPath(path); if (idx.isValid()) { treeViewDown->expand(idx); expandedPaths.insert(p); qDebug() << "成功恢复展开路径:" << p; } else { qDebug() << "未找到展开路径部分: " << p; } } m_blockItemChanged = false; } // 清空历史 void DbTreeViewManager::clearHistory() { m_backStack.clear(); m_forwardStack.clear(); buttonLeft->setIcon(QIcon(":/images/home_left_hide.png")); buttonRight->setIcon(QIcon(":/images/home_right.png")); } // 获取当前页面的 PageState DbTreeViewManager::PageState DbTreeViewManager::getCurrentPageState() { PageState st; st.isThirdLevel = false; st.directoryId = -1; // 判断是否在第三层窗口中 if (m_thirdLevelFieldWnd && m_thirdLevelFieldWnd->isVisible()) { // 如果此时是在第三层界面,则用当前导航栏 or 目录树的 “选中项” 来获取路径 QModelIndex curIndex = treeViewDown->currentIndex(); if (!curIndex.isValid()) { st.path << "未知目录"; } else { QStandardItem* item = model->itemFromIndex(curIndex); st.path = buildItemPath(item); } // 如果能拿到 DirectoryId,则置为第三层 QVariant dataVar = model->itemFromIndex(treeViewDown->currentIndex())->data(Qt::UserRole + 2); if (dataVar.canConvert()) { QJsonObject obj = dataVar.toJsonObject(); if (obj.contains("IsThirdLevel") && obj["IsThirdLevel"].toBool()) { st.isThirdLevel = true; st.directoryId = obj.value("Id").toInt(-1); st.multiTableName = obj.value("TableName").toString(); } } } else { // 当前是目录树界面,就看 treeView 选中项 QModelIndex curIndex = treeViewDown->currentIndex(); if (curIndex.isValid()) { QStandardItem* item = model->itemFromIndex(curIndex); st.path = buildItemPath(item); // 检查是否第三层 QVariant dataVar = item->data(Qt::UserRole + 2); if (dataVar.canConvert()) { QJsonObject obj = dataVar.toJsonObject(); if (obj.contains("IsThirdLevel") && obj["IsThirdLevel"].toBool()) { st.isThirdLevel = true; st.directoryId = obj.value("Id").toInt(-1); st.multiTableName = obj.value("TableName").toString(); } } } } return st; } //加载指定的 PageState:相当于“回到该路径”或“跳转到这个第三层” void DbTreeViewManager::loadPageState(const PageState &st, bool isByHistoryNav) { // 先根据 st.path 找到对应的节点 QModelIndex idx = findItemByPath(st.path); if (!idx.isValid()) { qWarning() << "[loadPageState] 未找到路径" << st.path; return; } // 选中该节点 treeViewDown->setCurrentIndex(idx); treeViewDown->scrollTo(idx); // 更新导航栏 updateNavigationBar(idx); // 如果是第三层,就加载对应的数据窗口 if (st.isThirdLevel && st.directoryId != -1) { // 如果当前已在一个第三层窗口,先关闭它 if (m_thirdLevelFieldWnd) { m_thirdLevelFieldWnd->close(); m_thirdLevelFieldWnd->deleteLater(); m_thirdLevelFieldWnd = nullptr; } int userPrivilege = 0x1; QList tableControlDatas; bool allChangeFlag = false; m_sqlOper->GetThirdDirControlData(st.multiTableName, userPrivilege, tableControlDatas, allChangeFlag); displayThirdLevelFields(tableControlDatas, allChangeFlag, false); // 传递参数表示 Home 界面 //QJsonObject data = fetchThirdLevelData(st.directoryId, userPrivilege); //displayThirdLevelFields(data, (m_currentConfigName == "Home")); } else { // 否则,显示目录树 if (m_thirdLevelFieldWnd) { m_thirdLevelFieldWnd->close(); m_thirdLevelFieldWnd->deleteLater(); m_thirdLevelFieldWnd = nullptr; } treeViewDown->show(); for (auto sep : firstLevelSeparators) { if (sep) sep->show(); } } if (!isByHistoryNav) { m_forwardStack.clear(); buttonRight->setIcon(QIcon(":/images/home_right.png")); // 把新状态压入后退栈 m_backStack.append(st); if(m_backStack.size() >= 2){ buttonLeft->setIcon(QIcon(":/images/home_left.png")); } } } void DbTreeViewManager::loginput(const QString& fieldTableName, const QString& fieldName,const QString& modifies){ // 获取当前时间并格式化 QDateTime currentDateTime = QDateTime::currentDateTime(); QString timestamp = currentDateTime.toString("yyyy-MM-dd hh:mm:ss"); QString logMessage = QString("%1 :fieldTableName is %2 and fieldName is %3 ,currentvalue is modified %4" ).arg(timestamp).arg(fieldTableName).arg(fieldName).arg(modifies); QString pathoflog = "C:\\Users\\Administrator\\Desktop\\qt\\merge\\gujiangdong\\die-bonder-ui0218\\die-bonder-ui\\log/log.txt"; writeLogToFile(logMessage,pathoflog); } void DbTreeViewManager::writeLogToFile(const QString& logMessage, const QString& filePath) { QFile logFile(filePath); if (!logFile.open(QIODevice::Append | QIODevice::Text)) { qWarning() << "Cannot open file for writing:" << filePath; return; } QTextStream out(&logFile); out << logMessage << "\n"; logFile.close(); }