123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572 |
- #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>()) {
- 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>()) {
- 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<QStandardItem *> 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<QWidget *>(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<QWidget *>(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>()) {
- 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: 返回上一级目录";
- }
|