1. 为什么选择QTreeView做导航菜单?
很多刚接触Qt GUI开发的朋友,尤其是从Web前端或者移动端转过来的,第一次看到原生的QTreeView控件,可能会觉得它有点“土”。默认的灰色边框、老式的折叠图标、略显呆板的行高和选中效果,直接拿来当应用的主导航菜单,确实和现代软件的视觉风格格格不入。我刚开始做桌面应用的时候也这么想,甚至动过自己从头用QWidget和paintEvent重画一个的念头。
但折腾了几次之后,我发现**“美化一个现有的强大控件,远比从头造一个轮子更划算”**。QTreeView作为Qt模型/视图框架的“三驾马车”之一,它的内核非常强大。它天然支持树形数据结构,这意味着你的导航菜单可以轻松实现多级嵌套,比如“系统设置”下面有“用户管理”、“日志管理”,“用户管理”下面又能有“添加用户”、“权限分配”。这种层级关系用QTreeView的模型来管理,简直是天作之合。
更重要的是,QTreeView的每个节点(QModelIndex)都可以携带一个QVariant类型的用户数据。这个特性太有用了!你可以把每个菜单项对应的页面指针、页面ID、或者一个跳转动作的lambda函数存进去。当用户点击某个菜单项时,你直接从节点数据里取出对应的页面或动作来执行,业务逻辑会变得非常清晰和模块化。
所以,我们的目标就很明确了:保留QTreeView强大的数据管理和交互内核,然后用Qt的样式表(QSS)和少量的代码“魔法”,给它换上一身漂亮的“外衣”。这就像给一辆性能强悍但内饰简陋的越野车,做一次全面的内饰升级和外观改装,让它既好开又好看。接下来,我就带你一步步完成这次“改装”。
2. 基础搭建:从零创建一个导航树
在开始涂脂抹粉之前,我们得先把骨架搭好。一个典型的导航菜单,其核心是数据模型和视图的绑定。在Qt里,QStandardItemModel是上手最快、最常用的模型之一,非常适合用来构建这种静态或半静态的树形菜单。
2.1 初始化模型与视图
首先,在你的主窗口类(比如MainWindow)的头文件里,声明好模型和视图。我习惯用QPointer来管理模型对象,它是Qt的智能指针,会在父对象销毁时自动清理,能有效避免内存泄漏。
// mainwindow.h
#include <QMainWindow>
#include <QPointer>
class QStandardItemModel;
class QModelIndex;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
// 处理树视图点击的槽函数
void onTreeViewClicked(const QModelIndex &index);
private:
Ui::MainWindow *ui;
QPointer<QStandardItemModel> m_navigationModel; // 使用智能指针
};
接下来是.cpp文件中的初始化工作。这一步的目标是创建一个干净的、去除了多余装饰的树视图,并为其填充导航数据。
// mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QStandardItemModel>
#include <QIcon>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
, m_navigationModel(nullptr)
{
ui->setupUi(this);
// 1. 创建模型
m_navigationModel = new QStandardItemModel(this);
// 2. 将模型设置给视图
ui->treeView->setModel(m_navigationModel);
// 3. 关键的基础配置:让QTreeView看起来像个菜单,而不是文件浏览器
ui->treeView->setHeaderHidden(true); // 隐藏表头,菜单不需要列标题
ui->treeView->setFocusPolicy(Qt::NoFocus); // 取消焦点框,视觉更干净
ui->treeView->setEditTriggers(QAbstractItemView::NoEditTr


3687

被折叠的 条评论
为什么被折叠?



