1. 项目的样式
2. 项目代码
头文件
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QSplitter>
#include <QStackedWidget>
#include <QDockWidget>
#include <QTextEdit>
#include <QListWidget>
#include <QTreeWidget>
#include <QPushButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QGroupBox>
#include <QTabWidget>
#include <QTableWidget>
#include <QComboBox>QT_BEGIN_NAMESPACE
namespace Ui
{class MainWindow;
}
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:// StackedWidget相关槽函数void switchToPage1();void switchToPage2();void switchToPage3();void onComboBoxChanged(int index);// Dock相关槽函数void toggleLeftDock();void toggleRightDock();void toggleBottomDock();private:void setupUI(); // 初始化界面void setupSplitter(); // 设置分割器void setupStackedWidget(); // 设置堆叠控件void setupDockWidgets(); // 设置停靠控件void setupMenuAndToolbar(); // 设置菜单和工具栏Ui::MainWindow *ui;// Splitter相关成员QSplitter *mainSplitter; // 主分割器(垂直)QSplitter *topSplitter; // 顶部分割器(水平)QSplitter *bottomSplitter; // 底部分割器(水平)// StackedWidget相关成员QStackedWidget *stackedWidget; // 堆叠控件QWidget *page1; // 页面1:文本编辑器QWidget *page2; // 页面2:表格控件QWidget *page3; // 页面3:树形控件QComboBox *pageSelector; // 页面选择器// 各页面的控件QTextEdit *textEdit; // 文本编辑器QTableWidget *tableWidget; // 表格控件QTreeWidget *treeWidget; // 树形控件// Dock相关成员QDockWidget *leftDock; // 左侧停靠窗口QDockWidget *rightDock; // 右侧停靠窗口QDockWidget *bottomDock; // 底部停靠窗口// Dock内容控件QListWidget *projectList; // 项目列表QTextEdit *propertyEditor; // 属性编辑器QTextEdit *outputConsole; // 输出控制台// 控制按钮QPushButton *page1Btn;QPushButton *page2Btn;QPushButton *page3Btn;
};
#endif // MAINWINDOW_H
cpp文件
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QApplication>
#include <QHeaderView>
#include <QTreeWidgetItem>
#include <QTableWidgetItem>
#include <QMenuBar>
#include <QToolBar>
#include <QAction>
#include <QMessageBox>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow), mainSplitter(nullptr), topSplitter(nullptr), bottomSplitter(nullptr), stackedWidget(nullptr), page1(nullptr), page2(nullptr), page3(nullptr), pageSelector(nullptr), textEdit(nullptr), tableWidget(nullptr), treeWidget(nullptr), leftDock(nullptr), rightDock(nullptr), bottomDock(nullptr), projectList(nullptr), propertyEditor(nullptr), outputConsole(nullptr), page1Btn(nullptr), page2Btn(nullptr), page3Btn(nullptr)
{ui->setupUi(this);// 设置窗口标题和大小setWindowTitle("Qt Layout Demo - Splitter, Dock, Stacked");resize(1200, 800);// 初始化界面setupUI();setupSplitter();setupStackedWidget();setupDockWidgets();setupMenuAndToolbar();
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::setupUI()
{/*** 设置基本UI结构* 使用QSplitter创建可调节大小的分割区域*/// 创建主分割器(垂直分割)mainSplitter = new QSplitter(Qt::Vertical, this);setCentralWidget(mainSplitter);// 创建顶部分割器(水平分割)topSplitter = new QSplitter(Qt::Horizontal);// 创建底部分割器(水平分割)bottomSplitter = new QSplitter(Qt::Horizontal);// 将分割器添加到主分割器中mainSplitter->addWidget(topSplitter);mainSplitter->addWidget(bottomSplitter);// 设置分割器比例 (上下比例为 3:1)mainSplitter->setSizes({600, 200});mainSplitter->setStretchFactor(0, 3);mainSplitter->setStretchFactor(1, 1);
}void MainWindow::setupSplitter()
{/*** 设置分割器的详细配置* QSplitter允许用户通过拖拽来调整子控件的大小*/// 配置主分割器mainSplitter->setHandleWidth(3); // 设置分割线宽度mainSplitter->setChildrenCollapsible(false); // 禁止子控件折叠// 配置顶部分割器topSplitter->setHandleWidth(3);topSplitter->setChildrenCollapsible(false);// 配置底部分割器bottomSplitter->setHandleWidth(3);bottomSplitter->setChildrenCollapsible(false);
}void MainWindow::setupStackedWidget()
{/*** 设置堆叠控件* QStackedWidget用于在同一位置显示多个页面,一次只显示一个页面*/// 创建堆叠控件stackedWidget = new QStackedWidget();// 创建控制面板QWidget *controlPanel = new QWidget();QVBoxLayout *controlLayout = new QVBoxLayout(controlPanel);// 创建页面选择器pageSelector = new QComboBox();pageSelector->addItem("页面1 - 文本编辑器");pageSelector->addItem("页面2 - 表格控件");pageSelector->addItem("页面3 - 树形控件");// 创建按钮控制QGroupBox *buttonGroup = new QGroupBox("页面切换按钮");QHBoxLayout *buttonLayout = new QHBoxLayout(buttonGroup);page1Btn = new QPushButton("文本编辑器");page2Btn = new QPushButton("表格控件");page3Btn = new QPushButton("树形控件");page1Btn->setCheckable(true);page2Btn->setCheckable(true);page3Btn->setCheckable(true);page1Btn->setChecked(true); // 默认选中第一页buttonLayout->addWidget(page1Btn);buttonLayout->addWidget(page2Btn);buttonLayout->addWidget(page3Btn);// 添加到控制面板controlLayout->addWidget(new QLabel("使用下拉框选择页面:"));controlLayout->addWidget(pageSelector);controlLayout->addWidget(buttonGroup);controlLayout->addStretch();// 创建页面1:文本编辑器page1 = new QWidget();QVBoxLayout *page1Layout = new QVBoxLayout(page1);page1Layout->addWidget(new QLabel("页面1 - 文本编辑器"));textEdit = new QTextEdit();textEdit->setPlainText("这是一个文本编辑器示例。\n\n""QStackedWidget特点:\n""1. 可以在同一位置显示多个页面\n""2. 一次只显示一个页面\n""3. 适用于向导、选项卡等场景\n""4. 支持动画切换效果\n\n""您可以在这里编辑文本...");page1Layout->addWidget(textEdit);// 创建页面2:表格控件page2 = new QWidget();QVBoxLayout *page2Layout = new QVBoxLayout(page2);page2Layout->addWidget(new QLabel("页面2 - 表格控件"));tableWidget = new QTableWidget(5, 4);QStringList headers = {"姓名", "年龄", "部门", "工资"};tableWidget->setHorizontalHeaderLabels(headers);// 填充示例数据QString data[5][4] = {{"张三", "25", "开发部", "8000"},{"李四", "30", "测试部", "7500"},{"王五", "28", "设计部", "7000"},{"赵六", "32", "产品部", "9000"},{"钱七", "26", "运营部", "6500"}};for (int i = 0; i < 5; i++){for (int j = 0; j < 4; j++){tableWidget->setItem(i, j, new QTableWidgetItem(data[i][j]));}}tableWidget->horizontalHeader()->setStretchLastSection(true);page2Layout->addWidget(tableWidget);// 创建页面3:树形控件page3 = new QWidget();QVBoxLayout *page3Layout = new QVBoxLayout(page3);page3Layout->addWidget(new QLabel("页面3 - 树形控件"));treeWidget = new QTreeWidget();treeWidget->setHeaderLabels({"项目结构", "类型", "大小"});// 创建树形结构QTreeWidgetItem *root = new QTreeWidgetItem(treeWidget, {"项目根目录", "文件夹", ""});QTreeWidgetItem *src = new QTreeWidgetItem(root, {"src", "文件夹", ""});new QTreeWidgetItem(src, {"main.cpp", "C++文件", "2.1KB"});new QTreeWidgetItem(src, {"mainwindow.cpp", "C++文件", "8.5KB"});new QTreeWidgetItem(src, {"mainwindow.h", "头文件", "1.2KB"});QTreeWidgetItem *resources = new QTreeWidgetItem(root, {"resources", "文件夹", ""});new QTreeWidgetItem(resources, {"icons", "文件夹", ""});new QTreeWidgetItem(resources, {"images", "文件夹", ""});QTreeWidgetItem *build = new QTreeWidgetItem(root, {"build", "文件夹", ""});new QTreeWidgetItem(build, {"debug", "文件夹", ""});new QTreeWidgetItem(build, {"release", "文件夹", ""});treeWidget->expandAll();page3Layout->addWidget(treeWidget);// 将页面添加到堆叠控件stackedWidget->addWidget(page1);stackedWidget->addWidget(page2);stackedWidget->addWidget(page3);// 设置默认页面stackedWidget->setCurrentIndex(0);// 将控制面板和堆叠控件添加到顶部分割器topSplitter->addWidget(controlPanel);topSplitter->addWidget(stackedWidget);// 设置比例 (控制面板:主内容 = 1:4)topSplitter->setSizes({200, 800});// 连接信号和槽connect(pageSelector, QOverload<int>::of(&QComboBox::currentIndexChanged),this, &MainWindow::onComboBoxChanged);connect(page1Btn, &QPushButton::clicked, this, &MainWindow::switchToPage1);connect(page2Btn, &QPushButton::clicked, this, &MainWindow::switchToPage2);connect(page3Btn, &QPushButton::clicked, this, &MainWindow::switchToPage3);
}void MainWindow::setupDockWidgets()
{/*** 设置停靠控件* QDockWidget可以停靠在主窗口的四周,用户可以拖拽移动或关闭*/// 创建左侧停靠窗口 - 项目浏览器leftDock = new QDockWidget("项目浏览器", this);projectList = new QListWidget();// 添加项目列表项QStringList projects = {"项目1 - Qt应用程序","项目2 - Web前端","项目3 - 移动应用","项目4 - 数据分析","项目5 - 机器学习","项目6 - 游戏开发"};projectList->addItems(projects);leftDock->setWidget(projectList);// 设置停靠区域和特性leftDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);leftDock->setFeatures(QDockWidget::DockWidgetMovable |QDockWidget::DockWidgetClosable |QDockWidget::DockWidgetFloatable);// 创建右侧停靠窗口 - 属性编辑器rightDock = new QDockWidget("属性编辑器", this);propertyEditor = new QTextEdit();propertyEditor->setPlainText("属性编辑器\n\n""在这里可以编辑选中对象的属性:\n\n""对象名称: MainWindow\n""类型: QMainWindow\n""宽度: 1200\n""高度: 800\n""可见: true\n""启用: true\n\n""QDockWidget特点:\n""1. 可以停靠在窗口四周\n""2. 支持拖拽移动\n""3. 可以浮动显示\n""4. 可以隐藏/显示");rightDock->setWidget(propertyEditor);rightDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);rightDock->setFeatures(QDockWidget::DockWidgetMovable |QDockWidget::DockWidgetClosable |QDockWidget::DockWidgetFloatable);// 创建底部停靠窗口 - 输出控制台bottomDock = new QDockWidget("输出控制台", this);outputConsole = new QTextEdit();outputConsole->setPlainText("输出控制台\n""======================\n""[INFO] 应用程序启动成功\n""[INFO] 界面组件初始化完成\n""[INFO] Splitter配置完成\n""[INFO] StackedWidget配置完成\n""[INFO] DockWidget配置完成\n""[DEBUG] 当前页面: 文本编辑器\n""[INFO] 准备就绪,等待用户操作...\n");bottomDock->setWidget(outputConsole);bottomDock->setAllowedAreas(Qt::BottomDockWidgetArea | Qt::TopDockWidgetArea);bottomDock->setFeatures(QDockWidget::DockWidgetMovable |QDockWidget::DockWidgetClosable |QDockWidget::DockWidgetFloatable);// 添加停靠窗口到主窗口addDockWidget(Qt::LeftDockWidgetArea, leftDock);addDockWidget(Qt::RightDockWidgetArea, rightDock);addDockWidget(Qt::BottomDockWidgetArea, bottomDock);// 设置停靠窗口的大小resizeDocks({leftDock}, {200}, Qt::Horizontal);resizeDocks({rightDock}, {250}, Qt::Horizontal);resizeDocks({bottomDock}, {150}, Qt::Vertical);// 创建一个简单的状态显示控件添加到底部分割器QTextEdit *statusDisplay = new QTextEdit();statusDisplay->setPlainText("状态显示区域\n\n""这里显示应用程序的运行状态信息。\n\n""分割器使用说明:\n""- 可以通过拖拽分割线调整区域大小\n""- 支持嵌套分割(水平和垂直)\n""- 可以设置最小/最大尺寸\n""- 支持比例分配");statusDisplay->setMaximumHeight(200);bottomSplitter->addWidget(statusDisplay);
}void MainWindow::setupMenuAndToolbar()
{/*** 设置菜单栏和工具栏*/// 创建菜单QMenu *viewMenu = menuBar()->addMenu("视图(&V)");QMenu *windowMenu = menuBar()->addMenu("窗口(&W)");// 添加停靠窗口切换动作QAction *toggleLeftAction = new QAction("切换项目浏览器", this);QAction *toggleRightAction = new QAction("切换属性编辑器", this);QAction *toggleBottomAction = new QAction("切换输出控制台", this);toggleLeftAction->setCheckable(true);toggleRightAction->setCheckable(true);toggleBottomAction->setCheckable(true);toggleLeftAction->setChecked(true);toggleRightAction->setChecked(true);toggleBottomAction->setChecked(true);viewMenu->addAction(toggleLeftAction);viewMenu->addAction(toggleRightAction);viewMenu->addAction(toggleBottomAction);// 连接菜单动作connect(toggleLeftAction, &QAction::triggered, this, &MainWindow::toggleLeftDock);connect(toggleRightAction, &QAction::triggered, this, &MainWindow::toggleRightDock);connect(toggleBottomAction, &QAction::triggered, this, &MainWindow::toggleBottomDock);// 添加窗口操作菜单QAction *aboutAction = new QAction("关于", this);windowMenu->addAction(aboutAction);connect(aboutAction, &QAction::triggered, [this](){ QMessageBox::about(this, "关于","Qt Layout Demo\n\n""这个示例展示了Qt中三种重要的布局控件:\n\n""1. QSplitter - 分割器控件\n""2. QDockWidget - 停靠控件\n""3. QStackedWidget - 堆叠控件\n\n""通过这些控件的组合使用,可以创建出功能丰富、\n""用户体验良好的桌面应用程序界面。"); });// 创建工具栏QToolBar *mainToolBar = addToolBar("主工具栏");mainToolBar->addAction("新建");mainToolBar->addAction("打开");mainToolBar->addAction("保存");mainToolBar->addSeparator();mainToolBar->addAction("运行");mainToolBar->addAction("调试");
}// StackedWidget相关槽函数实现
void MainWindow::switchToPage1()
{stackedWidget->setCurrentIndex(0);pageSelector->setCurrentIndex(0);// 更新按钮状态page1Btn->setChecked(true);page2Btn->setChecked(false);page3Btn->setChecked(false);// 更新输出控制台outputConsole->append("[INFO] 切换到页面1 - 文本编辑器");
}void MainWindow::switchToPage2()
{stackedWidget->setCurrentIndex(1);pageSelector->setCurrentIndex(1);// 更新按钮状态page1Btn->setChecked(false);page2Btn->setChecked(true);page3Btn->setChecked(false);// 更新输出控制台outputConsole->append("[INFO] 切换到页面2 - 表格控件");
}void MainWindow::switchToPage3()
{stackedWidget->setCurrentIndex(2);pageSelector->setCurrentIndex(2);// 更新按钮状态page1Btn->setChecked(false);page2Btn->setChecked(false);page3Btn->setChecked(true);// 更新输出控制台outputConsole->append("[INFO] 切换到页面3 - 树形控件");
}void MainWindow::onComboBoxChanged(int index)
{stackedWidget->setCurrentIndex(index);// 更新按钮状态page1Btn->setChecked(index == 0);page2Btn->setChecked(index == 1);page3Btn->setChecked(index == 2);// 更新输出控制台QString pages[] = {"文本编辑器", "表格控件", "树形控件"};outputConsole->append(QString("[INFO] 通过下拉框切换到页面%1 - %2").arg(index + 1).arg(pages[index]));
}// Dock相关槽函数实现
void MainWindow::toggleLeftDock()
{if (leftDock->isVisible()){leftDock->hide();outputConsole->append("[INFO] 隐藏项目浏览器");}else{leftDock->show();outputConsole->append("[INFO] 显示项目浏览器");}
}void MainWindow::toggleRightDock()
{if (rightDock->isVisible()){rightDock->hide();outputConsole->append("[INFO] 隐藏属性编辑器");}else{rightDock->show();outputConsole->append("[INFO] 显示属性编辑器");}
}void MainWindow::toggleBottomDock()
{if (bottomDock->isVisible()){bottomDock->hide();}else{bottomDock->show();outputConsole->append("[INFO] 切换输出控制台显示状态");}
}
3. 代码调用文字流程图
Qt Layout Demo 程序流程图┌─────────────────────────────────────────────────────────────────┐
│ 程序启动流程 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ main.cpp │
│ │ │
│ ▼ │
│ QApplication app(argc, argv) │
│ │ │
│ ▼ │
│ MainWindow window │
│ │ │
│ ▼ │
│ MainWindow构造函数 │
│ │ │
│ ├─────────────────────────────────────────┐ │
│ │ ui->setupUi(this) │ │
│ │ setWindowTitle() │ │
│ │ resize(1200, 800) │ │
│ │ setupUI() │ │
│ │ setupSplitter() │ 详细初始化流程 │
│ │ setupStackedWidget() │ │
│ │ setupDockWidgets() │ │
│ │ setupMenuAndToolbar() │ │
│ └─────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ window.show() │
│ │ │
│ ▼ │
│ app.exec() │
│ │
└─────────────────────────────────────────────────────────────────┘┌─────────────────────────────────────────────────────────────────┐
│ 1. setupUI()流程 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ mainSplitter = new QSplitter(Qt::Vertical, this) │
│ │ │
│ ▼ │
│ setCentralWidget(mainSplitter) │
│ │ │
│ ▼ │
│ topSplitter = new QSplitter(Qt::Horizontal) │
│ │ │
│ ▼ │
│ bottomSplitter = new QSplitter(Qt::Horizontal) │
│ │ │
│ ▼ │
│ mainSplitter->addWidget(topSplitter) │
│ mainSplitter->addWidget(bottomSplitter) │
│ │ │
│ ▼ │
│ mainSplitter->setSizes({600,200}) │
│ │
└─────────────────────────────────────────────────────────────────┘┌─────────────────────────────────────────────────────────────────┐
│ 2. setupSplitter()流程 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ mainSplitter->setHandleWidth(3) │
│ mainSplitter->setChildrenCollapsible(false) │
│ │ │
│ ▼ │
│ topSplitter->setHandleWidth(3) │
│ topSplitter->setChildrenCollapsible(false) │
│ │ │
│ ▼ │
│ bottomSplitter->setHandleWidth(3) │
│ bottomSplitter->setChildrenCollapsible(false) │
│ │
└─────────────────────────────────────────────────────────────────┘┌─────────────────────────────────────────────────────────────────┐
│ 3. setupStackedWidget()流程 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 创建堆叠控件: stackedWidget = new QStackedWidget │
│ │ │
│ ▼ │
│ 创建控制面板: │
│ controlPanel = new QWidget │
│ pageSelector = new QComboBox │
│ 按钮组 (page1Btn, page2Btn, page3Btn) │
│ │ │
│ ▼ │
│ 创建页面内容: │
│ page1 (文本编辑器) page2 (表格控件) page3 (树形控件) │
│ │ │
│ ▼ │
│ 添加页面到堆叠控件 │
│ │ │
│ ▼ │
│ 添加到分割器: │
│ topSplitter->addWidget(controlPanel) │
│ topSplitter->addWidget(stackedWidget) │
│ │ │
│ ▼ │
│ 连接信号和槽 │
│ │
└─────────────────────────────────────────────────────────────────┘┌─────────────────────────────────────────────────────────────────┐
│ 4. setupDockWidgets()流程 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 创建左侧停靠窗口 │
│ 创建右侧停靠窗口 │
│ 创建底部停靠窗口 │
│ │ │
│ ▼ │
│ 添加停靠窗口到主窗口 │
│ addDockWidget(Qt::LeftDockWidgetArea, leftDock) │
│ addDockWidget(Qt::RightDockWidgetArea, rightDock) │
│ addDockWidget(Qt::BottomDockWidgetArea, bottomDock) │
│ │ │
│ ▼ │
│ 设置停靠窗口大小 │
│ │ │
│ ▼ │
│ 创建状态显示控件 │
│ │
└─────────────────────────────────────────────────────────────────┘┌─────────────────────────────────────────────────────────────────┐
│ 5. setupMenuAndToolbar()流程 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 创建菜单: 视图(&V) 窗口(&W) │
│ │ │
│ ▼ │
│ 添加停靠窗口切换动作 │
│ │ │
│ ▼ │
│ 连接菜单动作到槽函数 │
│ │ │
│ ▼ │
│ 添加关于菜单 │
│ │ │
│ ▼ │
│ 创建工具栏: 主工具栏 │
│ │
└─────────────────────────────────────────────────────────────────┘┌─────────────────────────────────────────────────────────────────┐
│ 用户交互流程 │
├─────────────────────────────────────────────────────────────────┤
│ 页面切换操作: │
│ 用户点击页面按钮 或 选择下拉框选项 │
│ │ │
│ ▼ │
│ 信号发出: clicked() 或 currentIndexChanged │
│ │ │
│ ▼ │
│ 槽函数调用: switchToPage1()/switchToPage2()/switchToPage3() │
│ │ │
│ ▼ │
│ 执行页面切换 │
│ │
│ 停靠窗口切换操作: │
│ 用户点击菜单项 │
│ │ │
│ ▼ │
│ 信号发出: triggered() │
│ │ │
│ ▼ │
│ 槽函数调用: toggleLeftDock()/toggleRightDock()/toggleBottomDock()│
│ │ │
│ ▼ │
│ 执行切换操作 │
│ │
└─────────────────────────────────────────────────────────────────┘┌─────────────────────────────────────────────────────────────────┐
│ 内存管理流程 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ MainWindow析构函数 │
│ ~MainWindow() → delete ui │
│ │ │
│ ▼ │
│ Qt父子关系自动管理其他控件内存 │
│ (所有new出来的控件都通过父子关系自动管理,无需手动delete) │
│ │
└─────────────────────────────────────────────────────────────────┘