#include "treeviewmanager.h" TreeViewManager::TreeViewManager(QWidget *parent, QWidget *widget2) : QWidget(parent), widget2(widget2), treeViewDown(new QTreeView(widget2)), // 初始化 treeViewDown navigationWidget(nullptr), buttonOpenFile(nullptr), buttonUp(nullptr), buttonDown(nullptr), buttonLeft(nullptr), buttonRight(nullptr) { if (!widget2) { qWarning() << "TreeViewManager: widget2 未初始化"; return; } // 初始化目录树模型 downModel = new QStandardItemModel(this); treeViewDown->setModel(downModel); // 创建数据模型 //setupTreeData(); // 应用样式表 applyCustomStyles(); treeViewDown->setHeaderHidden(true); // 显示头部 treeViewDown->setGeometry(16, 106, widget2->width()-16, widget2->height() - 106); treeViewDown->setEditTriggers(QAbstractItemView::NoEditTriggers); treeViewDown->show(); qDebug() << "widget2 geometry:" << widget2->geometry(); qDebug() << "treeViewDown geometry:" << treeViewDown->geometry(); // 加载 JSON 数据 loadJsonFromFile(":/config/menu_config.json"); // 创建按钮并设置布局 setupButton(); // 创建导航栏 navigationWidget = new QWidget(widget2); navigationWidget->setGeometry(15, 15, 300, 74); navigationLayout = new QVBoxLayout(navigationWidget); navigationLayout->setContentsMargins(0, 0, 0, 0); navigationLayout->setSpacing(0); navigationWidget->show(); // 更新导航栏位置 updateNavigationWidgetGeometry(); connect(treeViewDown, &QTreeView::clicked, this, [=](const QModelIndex &index) { QStandardItem *item = downModel->itemFromIndex(index); if (!item) return; QVariant data = item->data(Qt::UserRole); if (data.canConvert()) { QJsonObject fields = data.toJsonObject(); displayThirdLevelFields(fields); // 显示三级目录字段 } }); connect(treeViewDown, &QTreeView::clicked, this, [=](const QModelIndex &index) { if (!index.isValid()) { qWarning() << "点击事件:索引无效"; return; } QStandardItem *item = downModel->itemFromIndex(index); if (!item) { qWarning() << "点击事件:未找到对应项"; return; } QVariant data = item->data(Qt::UserRole); if (data.canConvert()) { QJsonObject fields = data.toJsonObject(); if (fields.contains("isThirdLevel") && fields["isThirdLevel"].toBool()) { qDebug() << "加载三级目录字段内容:" << fields; // 更新导航栏 updateNavigationBar(index); // 显示三级目录字段内容 displayThirdLevelFields(fields); // 显示三级目录字段 treeViewDown->hide(); // 隐藏 treeViewDown return; } } // 即使是非三级目录,也更新导航栏 updateNavigationBar(index); qDebug() << "更新导航栏,目录项:" << item->text(); }); connect(buttonOpenFile, &QPushButton::clicked, this, &TreeViewManager::onButtonOpenFileClicked); connect(buttonUp, &QPushButton::clicked, this, &TreeViewManager::onButtonUpClicked); connect(buttonDown, &QPushButton::clicked, this, &TreeViewManager::onButtonDownClicked); connect(buttonLeft, &QPushButton::clicked, this, &TreeViewManager::onButtonLeftClicked); connect(buttonRight, &QPushButton::clicked, this, &TreeViewManager::onButtonRightClicked); } void TreeViewManager::loadJsonFromFile(const QString &filePath) { QFile jsonFile(filePath); if (!jsonFile.exists()) { qWarning() << "JSON 文件不存在:" << filePath; return; } if (!jsonFile.open(QIODevice::ReadOnly)) { qWarning() << "无法打开 JSON 文件:" << filePath; return; } QByteArray fileData = jsonFile.readAll(); jsonFile.close(); QJsonDocument jsonDoc = QJsonDocument::fromJson(fileData); if (jsonDoc.isNull() || !jsonDoc.isObject()) { qWarning() << "JSON 文件格式错误:" << filePath; return; } // 直接传递解析好的 JSON 文档 loadTreeData(jsonDoc); qDebug() << "JSON 数据加载完成"; } void TreeViewManager::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_up.png); } QTreeView::indicator:checked { image: url(:/images/home_down.png); } /* 背景透明 */ QTreeView { background: transparent; border: none; } )"); } void TreeViewManager::loadTreeData(const QJsonDocument &doc) { if (!doc.isObject()) { qWarning() << "无效的 JSON 结构"; return; } // qDebug() << "加载的 JSON 数据:" << doc.toJson(); buildTree(doc.object(), downModel->invisibleRootItem()); } void TreeViewManager::buildTree(const QJsonObject &jsonObj, QStandardItem *parent) { for (auto it = jsonObj.begin(); it != jsonObj.end(); ++it) { if (it.key() == "isThirdLevel") { qDebug() << "跳过 'isThirdLevel' 字段:" << it.key(); continue; // 跳过 "isThirdLevel" 字段 } QStandardItem *item = new QStandardItem(it.key()); item->setCheckable(true); // 添加多选框 parent->appendRow(item); if (it.value().isObject()) { QJsonObject childObj = it.value().toObject(); if (childObj.contains("isThirdLevel") && childObj["isThirdLevel"].toBool()) { // 是三级目录,存储整个对象到 UserRole item->setData(childObj, Qt::UserRole); qDebug() << "识别为三级目录:" << it.key(); } else { // 递归处理子目录 buildTree(childObj, item); } } } } // 更新导航栏位置和大小 void TreeViewManager::updateNavigationWidgetGeometry() { // 设置导航栏的宽度和高度 int navWidth = 300; // 固定宽度为 300 像素 int navHeight = 74; // 固定高度为 74 像素 // 设置导航栏的左上角位置 int navLeft = 15; // 距离 widget2 左边 15 像素 int navTop = 15; // 距离 widget2 顶部 15 像素 // 设置导航栏的几何位置 navigationWidget->setGeometry(navLeft, navTop, navWidth, navHeight); // 如果需要,刷新组件 navigationWidget->update(); qDebug() << "Updated navigationWidget geometry:" << navigationWidget->geometry(); } void TreeViewManager::updateNavigationBar(const QModelIndex &index) { if (!index.isValid()) { qWarning() << "导航栏更新失败:索引无效"; return; } QStandardItem *item = downModel->itemFromIndex(index); if (!item) { qWarning() << "导航栏更新失败:未找到对应项"; return; } qDebug() << "导航栏更新,目录项:" << item->text(); // 如果导航栏已有布局,先清理 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; while (item) { if (item->text() != "isThirdLevel") { // 排除 "isThirdLevel" 标识 path.prepend(item); // 从根节点开始 } item = item->parent(); } qDebug() << "导航路径:" << [path]() { QStringList pathNames; for (QStandardItem *p : path) { pathNames.append(p->text()); } return pathNames.join(" -> "); }(); // 创建新的导航栏布局 QVBoxLayout *newLayout = new QVBoxLayout; newLayout->setContentsMargins(0, 0, 0, 0); // 去除边距 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(12); // 设置字体大小 label->setFont(font); label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); // 左对齐且垂直居中 label->setFixedHeight(navigationWidget->height() / 3); // 每行高度均分导航栏高度 newLayout->addWidget(label); } // 设置布局并更新导航栏 navigationWidget->setLayout(newLayout); navigationWidget->update(); qDebug() << "导航栏更新完成:" << path.size() << "项"; } void TreeViewManager::displayThirdLevelFields(const QJsonObject &fields) { if (fields.isEmpty()) { qWarning() << "字段数据为空,无法显示"; return; } qDebug() << "显示的字段数据:" << fields; // 检查是否已存在字段窗口,防止重复创建 foreach (QObject *child, widget2->children()) { QWidget *childWidget = qobject_cast(child); if (childWidget && childWidget->windowTitle() == "字段展示") { qDebug() << "字段窗口已存在,关闭旧窗口"; childWidget->close(); } } QWidget *fieldWindow = new QWidget(widget2); // 使用 widget2 作为父窗口 fieldWindow->setWindowTitle("字段展示"); fieldWindow->setGeometry(treeViewDown->geometry()); QVBoxLayout *layout = new QVBoxLayout(fieldWindow); for (auto it = fields.begin(); it != fields.end(); ++it) { QString fieldName = it.key(); if (fieldName == "isThirdLevel") { continue; // 跳过 isThirdLevel 字段 } QJsonObject fieldConfig = it.value().toObject(); QHBoxLayout *fieldLayout = new QHBoxLayout; QLabel *label = new QLabel(fieldName); label->setFixedWidth(150); fieldLayout->addWidget(label); if (fieldConfig["type"].toString() == "input") { QLineEdit *lineEdit = new QLineEdit(fieldConfig["value"].toString()); fieldLayout->addWidget(lineEdit); qDebug() << "创建输入控件:" << fieldName << ", 默认值:" << fieldConfig["value"].toString(); } else if (fieldConfig["type"].toString() == "dropdown") { QComboBox *comboBox = new QComboBox; QJsonArray options = fieldConfig["options"].toArray(); for (const QJsonValue &option : options) { comboBox->addItem(option.toString()); } comboBox->setCurrentText(fieldConfig["value"].toString()); fieldLayout->addWidget(comboBox); qDebug() << "创建下拉框:" << fieldName << ", 选项:" << options << ", 默认值:" << fieldConfig["value"].toString(); } else if (fieldConfig["type"].toString() == "checkbox") { QCheckBox *checkBox = new QCheckBox; checkBox->setChecked(fieldConfig["value"].toString() == "true"); fieldLayout->addWidget(checkBox); qDebug() << "创建复选框:" << fieldName << ", 默认值:" << fieldConfig["value"].toString(); } else { qWarning() << "未知字段类型:" << fieldConfig["type"].toString(); } layout->addLayout(fieldLayout); } fieldWindow->setLayout(layout); fieldWindow->adjustSize(); fieldWindow->show(); qDebug() << "三级目录字段窗口已打开"; } void TreeViewManager::setupButton() { buttonOpenFile = new QPushButton(widget2); buttonUp = new QPushButton(widget2); buttonDown = new QPushButton(widget2); buttonLeft = new QPushButton(widget2); buttonRight = new QPushButton(widget2); // 设置 buttonOpenFile 的位置 buttonOpenFile->setParent(widget2); // 明确设置 widget2 为父级 buttonOpenFile->setMaximumSize(76, 30); buttonOpenFile->setIcon(QIcon(":/images/home_openFile.png")); buttonOpenFile->setText(""); buttonOpenFile->setGeometry(328, 16, 76, 30); // 设置按钮位置大小 buttonUp->setParent(widget2); buttonUp->setMaximumSize(36, 30); buttonUp->setIcon(QIcon(":/images/home_up.png")); buttonUp->setText(""); buttonUp->setGeometry(408, 16, 36, 30); // 位置示例 buttonDown->setParent(widget2); buttonDown->setMaximumSize(36, 30); buttonDown->setIcon(QIcon(":/images/home_down.png")); buttonDown->setText(""); buttonDown->setGeometry(408, 50, 36, 30); // 位置示例 buttonLeft->setParent(widget2); buttonLeft->setMaximumSize(36, 30); buttonLeft->setIcon(QIcon(":/images/home_left.png")); buttonLeft->setText(""); buttonLeft->setGeometry(328, 50, 36, 30); // 位置示例 buttonRight->setParent(widget2); buttonRight->setMaximumSize(36, 30); buttonRight->setIcon(QIcon(":/images/home_right.png")); buttonRight->setText(""); buttonRight->setGeometry(368, 50, 36, 30); // 位置示例 // 显示所有按钮 buttonOpenFile->show(); buttonUp->show(); buttonDown->show(); buttonLeft->show(); buttonRight->show(); } void TreeViewManager::onButtonOpenFileClicked() { foreach (QObject *child, widget2->children()) { QWidget *childWidget = qobject_cast(child); if (childWidget && childWidget->windowTitle() == "字段展示") { qDebug() << "关闭字段窗口:" << childWidget; childWidget->close(); } } treeViewDown->show(); // 显示 treeViewDown treeViewDown->collapseAll(); // 收起所有节点 treeViewDown->clearSelection(); // 展开一级目录 QStandardItem *rootItem = downModel->invisibleRootItem(); if (rootItem) { for (int i = 0; i < rootItem->rowCount(); ++i) { QStandardItem *childItem = rootItem->child(i); if (childItem) { treeViewDown->expand(downModel->indexFromItem(childItem)); qDebug() << "展开一级目录:" << childItem->text(); } } } // 重置导航栏 updateNavigationBar(QModelIndex()); qDebug() << "成功返回到一级菜单"; } void TreeViewManager::onButtonUpClicked() { qDebug() << "TreeViewManager: 遍历导航向上"; // 检查当前是否有选中的索引 QModelIndex currentIndex = treeViewDown->currentIndex(); if (!currentIndex.isValid()) { qDebug() << "没有选中的索引,无法向上遍历"; return; } // 获取父项索引 QModelIndex parentIndex = currentIndex.parent(); if (!parentIndex.isValid()) { qDebug() << "当前已在顶级目录,无法向上遍历"; return; } // 将父项设置为当前选中项 treeViewDown->setCurrentIndex(parentIndex); // 获取父级菜单的内容 QStandardItem *parentItem = downModel->itemFromIndex(parentIndex); if (!parentItem) { qWarning() << "父项未找到,无法遍历"; return; } // 获取父项的数据 QVariant parentData = parentItem->data(Qt::UserRole); if (parentData.canConvert()) { QJsonObject fields = parentData.toJsonObject(); // 检查是否是三级菜单 if (fields.contains("type") && fields["type"].toString() == "三级菜单") { qDebug() << "跳过三级菜单的内容:" << parentItem->text(); return; } } qDebug() << "成功遍历到上一级菜单:" << parentItem->text(); } void TreeViewManager::onButtonDownClicked() { qDebug() << "TreeViewManager: 遍历导航向下"; QModelIndex currentIndex = treeViewDown->currentIndex(); if (!currentIndex.isValid()) { currentIndex = downModel->index(0, 0); // 从根节点第一个开始 } QModelIndex nextIndex = getNextIndex(currentIndex); while (nextIndex.isValid()) { QStandardItem *item = downModel->itemFromIndex(nextIndex); if (item && !item->data(Qt::UserRole).isValid()) { // 不是字段节点,导航到此项 treeViewDown->setCurrentIndex(nextIndex); updateNavigationBar(nextIndex); qDebug() << "成功导航到下一个目录:" << item->text(); return; } // 如果是字段节点,跳过 nextIndex = getNextIndex(nextIndex); } qDebug() << "已到达目录底部,无法继续向下遍历"; } // 获取下一个有效索引 QModelIndex TreeViewManager::getNextIndex(const QModelIndex ¤tIndex) { // 尝试获取当前项的下一个兄弟项 QModelIndex nextIndex = currentIndex.sibling(currentIndex.row() + 1, 0); if (nextIndex.isValid()) { return nextIndex; } // 如果没有兄弟项,向上找到父节点的下一个兄弟项 QModelIndex parentIndex = currentIndex.parent(); while (parentIndex.isValid()) { QModelIndex nextParentSibling = parentIndex.sibling(parentIndex.row() + 1, 0); if (nextParentSibling.isValid()) { return nextParentSibling; } parentIndex = parentIndex.parent(); // 再往上层找 } // 如果没有兄弟项或父节点兄弟项,返回无效索引 return QModelIndex(); } void TreeViewManager::onButtonLeftClicked() { qDebug() << "TreeViewManager: 进入下一级目录"; } void TreeViewManager::onButtonRightClicked() { qDebug() << "TreeViewManager: 返回上一级目录"; }