Qt 容器控件 #

容器控件概览 #

text
┌─────────────────────────────────────────────────────────────┐
│                    Qt 容器控件                               │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  分组容器:                                                  │
│  ├── QGroupBox        - 分组框                              │
│  └── QFrame           - 带边框的容器                        │
│                                                             │
│  多页容器:                                                  │
│  ├── QTabWidget       - 标签页控件                          │
│  ├── QStackedWidget   - 堆栈控件                            │
│  └── QToolBox         - 工具箱控件                          │
│                                                             │
│  滚动容器:                                                  │
│  ├── QScrollArea      - 滚动区域                            │
│  └── QMdiArea         - MDI 区域                            │
│                                                             │
│  分割容器:                                                  │
│  └── QSplitter        - 分割器                              │
│                                                             │
└─────────────────────────────────────────────────────────────┘

QGroupBox 分组框 #

基本使用 #

cpp
QGroupBox *groupBox = new QGroupBox("Options", this);

QVBoxLayout *layout = new QVBoxLayout(groupBox);
layout->addWidget(new QCheckBox("Option 1"));
layout->addWidget(new QCheckBox("Option 2"));
layout->addWidget(new QCheckBox("Option 3"));

// 设置标题
groupBox->setTitle("Settings");

// 设置对齐
groupBox->setAlignment(Qt::AlignLeft);
groupBox->setAlignment(Qt::AlignRight);
groupBox->setAlignment(Qt::AlignHCenter);

// 设置可选中
groupBox->setCheckable(true);
groupBox->setChecked(true);

// 连接信号
connect(groupBox, &QGroupBox::toggled, [](bool checked) {
    qDebug() << "GroupBox toggled:" << checked;
});

// 设置样式
groupBox->setStyleSheet(R"(
    QGroupBox {
        font-weight: bold;
        border: 2px solid gray;
        border-radius: 5px;
        margin-top: 10px;
        padding-top: 10px;
    }
    QGroupBox::title {
        subcontrol-origin: margin;
        left: 10px;
        padding: 0 5px;
    }
)");

QFrame 边框容器 #

基本使用 #

cpp
QFrame *frame = new QFrame(this);

// 设置边框样式
frame->setFrameStyle(QFrame::Box | QFrame::Plain);
frame->setFrameStyle(QFrame::Panel | QFrame::Raised);
frame->setFrameStyle(QFrame::StyledPanel);
frame->setFrameStyle(QFrame::NoFrame);

// 设置线宽
frame->setLineWidth(2);
frame->setMidLineWidth(1);

// 设置形状
frame->setFrameShape(QFrame::Box);       // 矩形框
frame->setFrameShape(QFrame::Panel);     // 面板
frame->setFrameShape(QFrame::WinPanel);  // Windows 风格面板
frame->setFrameShape(QFrame::HLine);     // 水平线
frame->setFrameShape(QFrame::VLine);     // 垂直线

// 设置阴影
frame->setFrameShadow(QFrame::Plain);    // 平面
frame->setFrameShadow(QFrame::Raised);   // 凸起
frame->setFrameShadow(QFrame::Sunken);   // 凹陷

QTabWidget 标签页 #

基本使用 #

cpp
QTabWidget *tabWidget = new QTabWidget(this);

// 添加标签页
QWidget *page1 = new QWidget;
QVBoxLayout *layout1 = new QVBoxLayout(page1);
layout1->addWidget(new QLabel("Page 1 Content"));
tabWidget->addTab(page1, "Tab 1");

QWidget *page2 = new QWidget;
QVBoxLayout *layout2 = new QVBoxLayout(page2);
layout2->addWidget(new QLabel("Page 2 Content"));
tabWidget->addTab(page2, "Tab 2");

// 添加带图标的标签页
QWidget *page3 = new QWidget;
tabWidget->addTab(page3, QIcon(":/icon.png"), "Tab 3");

// 插入标签页
tabWidget->insertTab(0, new QWidget, "First Tab");

// 移除标签页
tabWidget->removeTab(0);

// 获取标签页数量
int count = tabWidget->count();

// 获取当前标签页索引
int index = tabWidget->currentIndex();

// 设置当前标签页
tabWidget->setCurrentIndex(1);
tabWidget->setCurrentWidget(page2);

标签页样式 #

cpp
// 标签位置
tabWidget->setTabPosition(QTabWidget::North);  // 顶部(默认)
tabWidget->setTabPosition(QTabWidget::South);  // 底部
tabWidget->setTabPosition(QTabWidget::West);   // 左侧
tabWidget->setTabPosition(QTabWidget::East);   // 右侧

// 标签形状
tabWidget->setTabShape(QTabWidget::Rounded);  // 圆角(默认)
tabWidget->setTabShape(QTabWidget::Triangular);  // 三角形

// 可关闭
tabWidget->setTabsClosable(true);

// 可移动
tabWidget->setMovable(true);

// 文档模式
tabWidget->setDocumentMode(true);

// 设置标签文本
tabWidget->setTabText(0, "New Name");

// 设置标签图标
tabWidget->setTabIcon(0, QIcon(":/new-icon.png"));

// 设置标签提示
tabWidget->setTabToolTip(0, "Tooltip text");

// 启用/禁用标签
tabWidget->setTabEnabled(0, false);

信号处理 #

cpp
// 当前标签改变
connect(tabWidget, &QTabWidget::currentChanged, [](int index) {
    qDebug() << "Current tab:" << index;
});

// 标签关闭请求
connect(tabWidget, &QTabWidget::tabCloseRequested, [](int index) {
    qDebug() << "Close tab:" << index;
});

// 标签栏双击
connect(tabWidget, &QTabWidget::tabBarDoubleClicked, [](int index) {
    qDebug() << "Tab double clicked:" << index;
});

QStackedWidget 堆栈控件 #

基本使用 #

cpp
QStackedWidget *stackedWidget = new QStackedWidget(this);

// 添加页面
QWidget *page1 = new QWidget;
page1->setLayout(new QVBoxLayout);
page1->layout()->addWidget(new QLabel("Page 1"));
stackedWidget->addWidget(page1);

QWidget *page2 = new QWidget;
page2->setLayout(new QVBoxLayout);
page2->layout()->addWidget(new QLabel("Page 2"));
stackedWidget->addWidget(page2);

QWidget *page3 = new QWidget;
page3->setLayout(new QVBoxLayout);
page3->layout()->addWidget(new QLabel("Page 3"));
stackedWidget->addWidget(page3);

// 切换页面
stackedWidget->setCurrentIndex(1);
stackedWidget->setCurrentWidget(page3);

// 获取当前索引
int index = stackedWidget->currentIndex();

// 获取页面数量
int count = stackedWidget->count();

// 移除页面
QWidget *removed = stackedWidget->removeWidget(page1);

与导航按钮配合 #

cpp
QWidget *window = new QWidget;
QVBoxLayout *mainLayout = new QVBoxLayout(window);

// 导航按钮
QHBoxLayout *navLayout = new QHBoxLayout;
QPushButton *prevBtn = new QPushButton("Previous");
QPushButton *nextBtn = new QPushButton("Next");
navLayout->addWidget(prevBtn);
navLayout->addStretch();
navLayout->addWidget(nextBtn);

// 堆栈控件
QStackedWidget *stack = new QStackedWidget;
stack->addWidget(new QLabel("Page 1"));
stack->addWidget(new QLabel("Page 2"));
stack->addWidget(new QLabel("Page 3"));

// 连接信号
connect(prevBtn, &QPushButton::clicked, [=]() {
    int index = stack->currentIndex();
    if (index > 0) {
        stack->setCurrentIndex(index - 1);
    }
});

connect(nextBtn, &QPushButton::clicked, [=]() {
    int index = stack->currentIndex();
    if (index < stack->count() - 1) {
        stack->setCurrentIndex(index + 1);
    }
});

mainLayout->addLayout(navLayout);
mainLayout->addWidget(stack);

window->show();

QScrollArea 滚动区域 #

基本使用 #

cpp
QScrollArea *scrollArea = new QScrollArea(this);

// 设置内容控件
QWidget *contentWidget = new QWidget;
QVBoxLayout *layout = new QVBoxLayout(contentWidget);
for (int i = 0; i < 50; ++i) {
    layout->addWidget(new QPushButton(QString("Button %1").arg(i)));
}
contentWidget->setLayout(layout);

scrollArea->setWidget(contentWidget);

// 设置滚动策略
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);

// 设置控件可调整大小
scrollArea->setWidgetResizable(true);

// 设置对齐
scrollArea->setAlignment(Qt::AlignCenter);

滚动到指定位置 #

cpp
// 滚动到顶部
scrollArea->verticalScrollBar()->setValue(0);

// 滚动到底部
scrollArea->verticalScrollBar()->setValue(
    scrollArea->verticalScrollBar()->maximum());

// 滚动到指定控件
scrollArea->ensureWidgetVisible(button);

// 滚动到指定位置
scrollArea->horizontalScrollBar()->setValue(100);

QSplitter 分割器 #

基本使用 #

cpp
QSplitter *splitter = new QSplitter(Qt::Horizontal, this);

// 添加控件
QTextEdit *leftEdit = new QTextEdit;
QTextEdit *rightEdit = new QTextEdit;
splitter->addWidget(leftEdit);
splitter->addWidget(rightEdit);

// 设置初始大小比例
splitter->setSizes({200, 400});

// 设置拉伸因子
splitter->setStretchFactor(0, 1);
splitter->setStretchFactor(1, 3);

// 设置可折叠
splitter->setChildrenCollapsible(true);

// 设置手柄宽度
splitter->setHandleWidth(3);

// 设置不透明调整
splitter->setOpaqueResize(false);

// 嵌套分割器
QSplitter *mainSplitter = new QSplitter(Qt::Vertical);
QSplitter *topSplitter = new QSplitter(Qt::Horizontal);
topSplitter->addWidget(new QTextEdit);
topSplitter->addWidget(new QTextEdit);
mainSplitter->addWidget(topSplitter);
mainSplitter->addWidget(new QTextEdit);

保存和恢复状态 #

cpp
// 保存状态
QByteArray state = splitter->saveState();
QSettings settings;
settings.setValue("splitterState", state);

// 恢复状态
QByteArray state = settings.value("splitterState").toByteArray();
splitter->restoreState(state);

QToolBox 工具箱 #

基本使用 #

cpp
QToolBox *toolBox = new QToolBox(this);

// 添加页面
QWidget *page1 = new QWidget;
QVBoxLayout *layout1 = new QVBoxLayout(page1);
layout1->addWidget(new QPushButton("Button 1"));
layout1->addWidget(new QPushButton("Button 2"));
toolBox->addItem(page1, "Group 1");

QWidget *page2 = new QWidget;
QVBoxLayout *layout2 = new QVBoxLayout(page2);
layout2->addWidget(new QPushButton("Button 3"));
layout2->addWidget(new QPushButton("Button 4"));
toolBox->addItem(page2, QIcon(":/icon.png"), "Group 2");

// 设置当前页面
toolBox->setCurrentIndex(1);

// 获取页面数量
int count = toolBox->count();

// 设置页面标题
toolBox->setItemText(0, "New Title");

// 设置页面图标
toolBox->setItemIcon(0, QIcon(":/new-icon.png"));

// 启用/禁用页面
toolBox->setItemEnabled(0, false);

QMdiArea MDI 区域 #

基本使用 #

cpp
QMdiArea *mdiArea = new QMdiArea(this);

// 添加子窗口
QMdiSubWindow *subWindow1 = mdiArea->addSubWindow(new QTextEdit);
subWindow1->setWindowTitle("Document 1");

QMdiSubWindow *subWindow2 = mdiArea->addSubWindow(new QTextEdit);
subWindow2->setWindowTitle("Document 2");

// 设置窗口排列
mdiArea->cascadeSubWindows();    // 层叠
mdiArea->tileSubWindows();       // 平铺

// 设置视图模式
mdiArea->setViewMode(QMdiArea::SubWindowView);  // 子窗口模式
mdiArea->setViewMode(QMdiArea::TabbedView);     // 标签页模式

// 设置当前子窗口
mdiArea->setActiveSubWindow(subWindow1);

// 关闭子窗口
mdiArea->closeActiveSubWindow();
mdiArea->closeAllSubWindows();

下一步 #

现在你已经掌握了容器控件,接下来学习 输入控件,了解更多输入控件的使用方法!

最后更新:2026-03-29