文章目录
- QT_QT布局常用类QSplitter类与QDockWidget类
-
- QSplitter类(窗口分割)
- QDockWidget(停靠窗口)
- [**效果** !QT_QT布局常用类QSplitter类与QDockWidget类(https://i-blog.csdnimg.cn/direct/93c315d4ea0f4313b670b89d92b7b17f.png)](#效果
)
QT_QT布局常用类QSplitter类与QDockWidget类
QSplitter类(窗口分割)
QSplitter 是 Qt 中用于实现可拖拽分割窗口的布局组件,允许用户通过拖动分隔条来调整子控件的大小。
基本介绍
QSplitter 继承自 QFrame,它可以将多个子控件(Widget)按水平或垂直方向排列,并在控件之间插入一个可拖动的分隔条(Splitter Handle),用户可以拖动分隔条来动态调整各子控件所占的空间比例。头文件:
cpp
#include <QSplitter>
核心功能与常用 API
创建与方向
cpp
// 水平分割(子控件从左到右排列)
QSplitter *splitter = new QSplitter(Qt::Horizontal, parent);
// 垂直分割(子控件从上到下排列)
QSplitter *splitter = new QSplitter(Qt::Vertical, parent);
// 动态修改方向
splitter->setOrientation(Qt::Vertical);
添加子控件
cpp
QTextEdit *editor1 = new QTextEdit;
QTextEdit *editor2 = new QTextEdit;
splitter->addWidget(editor1);
splitter->addWidget(editor2);
设置初始大小比例
cpp
// 设置各子控件的初始宽度(或高度)比例
splitter->setSizes(QList<int>() << 200 << 300);
// 获取当前各子控件的大小
QList<int> sizes = splitter->sizes();
设置拉伸因子(Stretch Factor)
cpp
// 设置索引为0的子控件拉伸因子为1,索引为1的为2
// 当窗口拉伸时,第二个控件会获得更多额外空间
splitter->setStretchFactor(0, 1);
splitter->setStretchFactor(1, 2);
设置子控件可折叠
cpp
// 双击分隔条时,子控件是否可折叠为0
splitter->setChildrenCollapsible(false); // 禁止折叠(默认true)
// 针对特定子控件设置
splitter->setCollapsible(0, false); // 索引0的子控件不可折叠
嵌套使用(多级分割)
QSplitter 支持嵌套,可以实现复杂的分割布局:*
cpp
// 主分割器(水平)
QSplitter *mainSplitter = new QSplitter(Qt::Horizontal);
// 左侧:树形控件
QTreeWidget *tree = new QTreeWidget;
mainSplitter->addWidget(tree);
// 右侧:垂直分割器
QSplitter *rightSplitter = new QSplitter(Qt::Vertical);
QTextEdit *editor = new QTextEdit;
QTextBrowser *preview = new QTextBrowser;
rightSplitter->addWidget(editor);
rightSplitter->addWidget(preview);
mainSplitter->addWidget(rightSplitter);
自定义分割条样式
cpp
// 设置分隔条宽度
splitter->setHandleWidth(5);
// 通过样式表自定义外观
splitter->setStyleSheet(
"QSplitter::handle {"
" background-color: #cccccc;"
" width: 2px;" // 水平分割时
" height: 2px;" // 垂直分割时
"}"
"QSplitter::handle:hover {"
" background-color: #4a90d9;"
"}"
);
信号与槽
QSplitter 提供了以下常用信号:
cpp
// 分隔条被拖动时发射(参数为各子控件的新尺寸列表)
connect(splitter, &QSplitter::splitterMoved, [](int pos, int index) {qDebug() << "分隔条" << index << "移动到位置" << pos;
使用案例
cpp
#include "mainwindow.h"
#include <QSplitter>
#include <QTextEdit>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
// 1. 拆分窗口,分裂窗口布局
QSplitter *spMainWindow = new QSplitter(Qt::Horizontal,0);
QTextEdit *textEditMain = new QTextEdit("左边主窗口",spMainWindow);
// 2. 拆分右边部分窗口
QSplitter *spRight = new QSplitter(Qt::Vertical,spMainWindow);
QTextEdit *textEditUp = new QTextEdit("右边上窗口",spRight);
QTextEdit *textEditDown = new QTextEdit("右边下窗口",spRight);
// 3.
QSplitter *sptest = new QSplitter(Qt::Vertical,spRight);
QTextEdit *texteidttest = new QTextEdit("abcdQT开发",spRight);
spMainWindow->setWindowTitle("Splitter类才分窗口测试");
spMainWindow->show();
}
MainWindow::~MainWindow()
{
}
效果:

QDockWidget(停靠窗口)
QDockWidget 是 Qt 中用于创建可停靠、可浮动、可关闭的面板组件,常用于 IDE、图像处理软件等需要灵活布局的桌面应用。
基本介绍
QDockWidget 继承自 QWidget,它可以:
- 停靠在主窗口的四个边缘(上、下、左、右)
- 浮动为独立窗口
- 拖拽到不同位置
- 关闭/隐藏,并可通过菜单重新显示
头文件:
cpp
#include <QDockWidget>
核心功能与常用API
基本用法
cpp
// 创建主窗口
QMainWindow *mainWindow = new QMainWindow;
// 创建 DockWidget
QDockWidget *dock = new QDockWidget("属性面板", mainWindow);
dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
// 设置 Dock 的内容
QTreeWidget *tree = new QTreeWidget;
dock->setWidget(tree);
// 将 Dock 添加到主窗口
mainWindow->addDockWidget(Qt::LeftDockWidgetArea, dock);
注意:QDockWidget 必须作为 QMainWindow 的子控件使用,不能在普通 QWidget 中使用。
停靠区域
| 常量 | 位置 |
|---|---|
Qt::LeftDockWidgetArea |
左侧 |
Qt::RightDockWidgetArea |
右侧 |
Qt::TopDockWidgetArea |
顶部 |
Qt::BottomDockWidgetArea |
底部 |
功能特性设置
cpp
// 禁止浮动(只能停靠,不能拖出为独立窗口)
dock->setFeatures(dock->features() & ~QDockWidget::DockWidgetFloatable);
// 禁止关闭
dock->setFeatures(dock->features() & ~QDockWidget::DockWidgetClosable);
// 禁止移动
dock->setFeatures(dock->features() & ~QDockWidget::DockWidgetMovable);
// 一次性设置多个特性
dock->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable);
// 禁止所有特性(固定不可操作)
dock->setFeatures(QDockWidget::NoDockWidgetFeatures);
多个 DockWidget 的布局控制
选项卡化(Tab 页签模式)
cpp
QDockWidget *dock1 = new QDockWidget("面板1", mainWindow);
QDockWidget *dock2 = new QDockWidget("面板2", mainWindow);
mainWindow->addDockWidget(Qt::LeftDockWidgetArea, dock1);
mainWindow->addDockWidget(Qt::LeftDockWidgetArea, dock2);
// 将两个 Dock 以选项卡方式组合
mainWindow->tabifyDockWidget(dock1, dock2);
分割 DockWidget
cpp
// 在 dock1 的右侧分割出 dock2 的空间
mainWindow->splitDockWidget(dock1, dock2, Qt::Vertical);
嵌套 DockWidget(通过 QSplitter)
QDockWidget 本身不支持直接嵌套,但可以通过 QSplitter 间接实现:
cpp
QDockWidget *dock = new QDockWidget("组合面板", mainWindow);
QSplitter *splitter = new QSplitter(Qt::Vertical);
splitter->addWidget(new QTextEdit);
splitter->addWidget(new QTreeWidget);
dock->setWidget(splitter);
mainWindow->addDockWidget(Qt::BottomDockWidgetArea, dock);
常用信号
cpp
// 关闭按钮被点击
connect(dock, &QDockWidget::visibilityChanged, [](bool visible) {
// visible 为 false 时表示被关闭
});
// 顶层状态变化(浮动/停靠切换时触发)
connect(dock, &QDockWidget::topLevelChanged, [](bool topLevel) {
qDebug() << "是否浮动:" << topLevel;
});
// 停靠区域变化
connect(dock, &QDockWidget::dockLocationChanged, [](Qt::DockWidgetArea area) {
qDebug() << "新停靠区域:" << area;
});
ide经典布局案例
mainwindow.h代码:
cpp
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDockWidget>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
void DockWidgetFunc();
QDockWidget *dw1; // 项目面板
QDockWidget *dw2; // 属性面板
QDockWidget *dw3; // 输出面板
};
#endif // MAINWINDOW_H
mainwindow.cpp代码:
cpp
#include "mainwindow.h"
#include <QTextEdit>
#include <QDockWidget>
#include <QTreeWidget>
#include <QMenuBar>
#include <QMenu>
#include <QAction>
#include <QSplitter>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
DockWidgetFunc();
}
MainWindow::~MainWindow()
{
}
void MainWindow::DockWidgetFunc(){
setWindowTitle("QDockWidget 停靠窗口测试");
resize(800, 600);
// ========== 中心区域:主编辑器 ==========
QTextEdit *centralEditor = new QTextEdit;
centralEditor->setPlaceholderText("这里是主编辑区域...");
setCentralWidget(centralEditor);
// ========== 停靠窗口1:左侧项目树 ==========
dw1 = new QDockWidget("项目", this);
dw1->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable);
dw1->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
QTreeWidget *projectTree = new QTreeWidget;
projectTree->setHeaderLabel("项目文件");
// 添加示例节点
QTreeWidgetItem *srcItem = new QTreeWidgetItem(projectTree, QStringList("src"));
new QTreeWidgetItem(srcItem, QStringList("main.cpp"));
new QTreeWidgetItem(srcItem, QStringList("mainwindow.cpp"));
new QTreeWidgetItem(srcItem, QStringList("mainwindow.h"));
QTreeWidgetItem *resItem = new QTreeWidgetItem(projectTree, QStringList("resources"));
new QTreeWidgetItem(resItem, QStringList("icon.png"));
projectTree->expandAll();
dw1->setWidget(projectTree);
addDockWidget(Qt::LeftDockWidgetArea, dw1);
// ========== 停靠窗口2:右侧属性面板 ==========
dw2 = new QDockWidget("属性", this);
dw2->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable);
dw2->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
QTreeWidget *propTree = new QTreeWidget;
propTree->setColumnCount(2);
propTree->setHeaderLabels(QStringList() << "属性" << "值");
new QTreeWidgetItem(propTree, QStringList() << "objectName" << "centralWidget");
new QTreeWidgetItem(propTree, QStringList() << "geometry" << "0,0,800,600");
new QTreeWidgetItem(propTree, QStringList() << "windowTitle" << "MainWindow");
new QTreeWidgetItem(propTree, QStringList() << "enabled" << "true");
dw2->setWidget(propTree);
addDockWidget(Qt::RightDockWidgetArea, dw2);
// ========== 停靠窗口3:底部输出窗口 ==========
dw3 = new QDockWidget("输出", this);
dw3->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable);
dw3->setAllowedAreas(Qt::BottomDockWidgetArea | Qt::TopDockWidgetArea);
QTextEdit *outputEdit = new QTextEdit;
outputEdit->setReadOnly(true);
outputEdit->append("[信息] 程序启动成功");
outputEdit->append("[信息] 加载项目完成");
outputEdit->append("[警告] 未找到配置文件,使用默认设置");
dw3->setWidget(outputEdit);
addDockWidget(Qt::BottomDockWidgetArea, dw3);
// ========== 菜单栏:视图菜单控制 Dock 显隐 ==========
QMenu *viewMenu = menuBar()->addMenu("视图(&V)");
viewMenu->addAction(dw1->toggleViewAction()); // 项目面板
viewMenu->addAction(dw2->toggleViewAction()); // 属性面板
viewMenu->addAction(dw3->toggleViewAction()); // 输出面板
}
效果

end