在稍稍复杂一点客户端,需要承载许多内容,通常会采用左侧导航栏右侧内容页的框架布局。
用Qt实现可以简单的采用 QTreeWidget + QTabWidget来实现。
简单画一下界面
可以把左侧菜单导航配置到文件
menu.json
[
{
"name": "业务1",
"submenus": [
{
"name": "子业务1.1"
},
{
"name": "子业务1.2"
},
{
"name": "子业务1.3"
},
{
"name": "子业务1.4"
},
{
"name": "子业务1.5"
},
{
"name": "子业务1.6"
}
]
},
{
"name": "业务2",
"submenus": [
{
"name": "子业务2.1"
},
{
"name": "子业务2.2"
},
{
"name": "子业务2.3"
},
{
"name": "子业务2.4"
},
{
"name": "子业务2.5"
}
]
},
{
"name": "业务3",
"submenus": [
{
"name": "子业务3.1"
},
{
"name": "子业务3.2"
},
{
"name": "子业务3.3"
}
]
}
]
tree_menu_demo.h
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_tree_menu_demo.h"
#include <QJsonArray>
class tree_menu_demo : public QMainWindow
{
Q_OBJECT
public:
tree_menu_demo(QWidget *parent = Q_NULLPTR);
virtual void init();
protected:
virtual QJsonArray LoadMenuJson(const QString& filepath = ".\\menu.json");
virtual QList<QTreeWidgetItem*> ParseMenutree(const QJsonArray& menu);
protected slots:
void onTreeMenuItemChanged(QTreeWidgetItem *, QTreeWidgetItem *);
private:
Ui::tree_menu_demoClass ui;
};
tree_menu_demo .cpp
#include "tree_menu_demo.h"
#include <QTreeWidgetItem>
#include <QJsonDocument>
#include <QJsonObject>
#include <QFile>
tree_menu_demo::tree_menu_demo(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
init();
}
void tree_menu_demo::init()
{
QTabWidget* tab_widget = this->findChild<QTabWidget*>("tab_widget");
tab_widget->setTabBarAutoHide(true);
QTreeWidget* tree_menu = this->findChild<QTreeWidget*>("tree_menu");
tree_menu->setHeaderLabels({ QStringLiteral("菜单") });
tree_menu->setHeaderHidden(true);
const auto menujson = LoadMenuJson();
auto items = ParseMenutree(menujson);
tree_menu->addTopLevelItems(items);
connect(tree_menu, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(onTreeMenuItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
}
QJsonArray tree_menu_demo::LoadMenuJson(const QString& filepath/*=".\\menu.json"*/)
{
QFile file(filepath);
file.open(QIODevice::ReadOnly);
QByteArray bytearr = file.readAll();
QJsonDocument doc = QJsonDocument::fromJson(bytearr);
return doc.array();
}
QList<QTreeWidgetItem*> tree_menu_demo::ParseMenutree(const QJsonArray& menu)
{
QList<QTreeWidgetItem*> res;
for (int i = 0; i < menu.size(); ++i)
{
QJsonObject obj = menu[i].toObject();
QTreeWidgetItem* it = new QTreeWidgetItem();
it->setText(0, obj["name"].toString());
if (obj.contains("submenus")) {
it->addChildren(ParseMenutree(obj["submenus"].toArray()));
}
res.append(it);
}
return res;
}
void tree_menu_demo::onTreeMenuItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
{
QTabWidget* tab_content = this->findChild<QTabWidget*>("tab_content");
QWidget* w = tab_content->widget(0);
QLabel* lab = w->findChild<QLabel*>("label0");
QString line = (current ? current->text(0) : QString("")) + ":" + (previous ? previous->text(0) : QString(""));
QFontMetrics fm(lab->font());
QRect textRect = fm.boundingRect(line);
lab->setFixedSize(textRect.size() + QSize(10, 5)); // 加一些边距以防止紧贴文本
lab->setText(line);
}
运行效果