QT_QT布局常用类QSplitter窗口分割类与QDockWidget窗口停靠类

文章目录

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

相关推荐
老王生涯1 小时前
rust开发环境配置-Windows & GNU
开发语言·windows·rust
Yeauty1 小时前
自建 HLS 第一问:fMP4 还是 TS?用 Rust 在进程内把两种都跑出来
开发语言·后端·rust
小果因子实验室1 小时前
策略研究--qmt实现新股自动申购卖出策略
数据库
Darling噜啦啦1 小时前
从零实战Milvus向量数据库:用RAG打造你的AI日记助手
数据库
颜x小2 小时前
[C#]泛型类与泛型方法
开发语言·c++·c#
benben0442 小时前
大模型之基于PEFT的SFT微调实战篇
开发语言·python
Lhan.zzZ2 小时前
深入理解 windeployqt:混合 C++/Qt 项目的打包指南
开发语言·c++·qt
淼澄研学2 小时前
PyTorch深度学习实战:5个核心方法从0到1构建神经网络
前端·数据库·python
脑子进水养啥鱼?2 小时前
where id > ‘5‘ 的查询 sql 查不到 id = ‘10‘ 的数据?
数据库·sql·postgresql