
🔥草莓熊Lotso: 个人主页
❄️个人专栏: 《C++知识分享》 《Linux 入门到实践:零基础也能懂》
✨生活是默默的坚持,毅力是永久的享受!
🎬 博主简介:

文章目录
- 前言:
- [一. QMainWindow 组件布局概览](#一. QMainWindow 组件布局概览)
- [二. 菜单栏(Menu Bar):核心功能分类入口](#二. 菜单栏(Menu Bar):核心功能分类入口)
-
- [2.1 实战示例1:菜单栏 && 菜单 && 菜单项的基本使用](#2.1 实战示例1:菜单栏 && 菜单 && 菜单项的基本使用)
- [2.2 实战示例2:添加快捷键](#2.2 实战示例2:添加快捷键)
- [2.3 实战示例3:添加子菜单](#2.3 实战示例3:添加子菜单)
- [2.4 实战示例4:添加分割线和图标](#2.4 实战示例4:添加分割线和图标)
- [三. 工具栏(Tool Bar):常用功能快捷入口](#三. 工具栏(Tool Bar):常用功能快捷入口)
-
- [3.1 实战示例1:创建工具栏(基本使用)](#3.1 实战示例1:创建工具栏(基本使用))
- [3.2 实战示例2:多个工具栏的使用](#3.2 实战示例2:多个工具栏的使用)
- [四. 状态栏(Status Bar):状态信息展示区域](#四. 状态栏(Status Bar):状态信息展示区域)
-
- [4.1 实战示例:多功能状态栏(实时消息 + 文本 + 进度条 + 按钮)](#4.1 实战示例:多功能状态栏(实时消息 + 文本 + 进度条 + 按钮))
- [五. 浮动窗口(Dock Widget):辅助功能承载区域](#五. 浮动窗口(Dock Widget):辅助功能承载区域)
-
- [5.1 实战示例:浮动窗口的基本使用](#5.1 实战示例:浮动窗口的基本使用)
- [六. 核心组件避坑指南](#六. 核心组件避坑指南)
- 结语:
前言:
Qt 的
QMainWindow是构建桌面应用主窗口的核心类,它内置了一套标准化布局,包含菜单栏、工具栏、状态栏、浮动窗口(铆接部件)和中心部件五大核心组件。这些组件各司其职,共同构成了专业桌面应用的基础框架 ------ 菜单栏负责核心功能分类,工具栏提供快捷操作,状态栏显示状态信息,浮动窗口承载辅助功能,中心部件作为核心交互区域。本文逐一拆解 QMainWindow 四大核心组件(菜单栏、工具栏、状态栏、浮动窗口)的属性、创建方法和实战场景,通过可直接运行的代码示例,帮你快速掌握 Qt 主窗口的搭建技巧,轻松打造标准化桌面应用界面。
一. QMainWindow 组件布局概览
在开始实战前,先明确 QMainWindow 各组件的默认布局位置,避免后续开发中组件位置混乱:
- 菜单栏(Menu Bar):顶部标题栏下方,全局唯一,用于分类核心功能(如文件、编辑、帮助);
- 工具栏(Tool Bar):菜单栏下方或两侧,可多个共存,用于常用功能的快捷访问;
- 中心部件(Central Widget):窗口核心区域,占比最大,用于放置核心交互控件(如文本编辑、表格);
- 浮动窗口(Dock Widget):中心部件周围,可浮动可停靠,用于辅助功能(如日志、属性设置);
- 状态栏(Status Bar):窗口底部,全局唯一,用于显示实时状态、永久信息或进度提示。
所有组件均需依托 QMainWindow 作为父类,因此新建项目时需选择 QMainWindow 作为基类(而非 QWidget)。


二. 菜单栏(Menu Bar):核心功能分类入口
菜单栏是桌面应用的 "功能导航栏" ,通过层级结构(菜单栏 --> 菜单 --> 菜单项)组织核心功能,支持快捷键,分割线,是用户操作的主要入口。Qt 中通过 QMEnuBar(菜单栏),QMenu(菜单),QAction(菜单项) 三者配合实现。
核心属性与 API:
- 菜单栏创建 :
menuBar()(QMainWindow 内置方法,直接获取菜单栏对象)或new QMenuBar(this)(动态创建); - 菜单创建 :
new QMenu("菜单名称", this),通过menubar->addMenu(menu)添加到菜单栏; - 菜单项创建 :
new QAction("菜单项名称", this),通过menu->addAction(action)添加到菜单; - 关键功能 :
menu->addSeparator()(添加分割线)、
action->setShortcut(QKeySequence("Ctrl+S"))(设置快捷键)(还有别的方法看下面示例); - 核心信号 :
QAction::triggered()(菜单项被点击时触发)。
2.1 实战示例1:菜单栏 && 菜单 && 菜单项的基本使用
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 1.先创建一个菜单栏
QMenuBar* menuBar = this->menuBar();
// QMenuBar* menuBar = new QMenuBar();
this->setMenuBar(menuBar);
// 2.创建菜单
QMenu* menu1 = new QMenu("文件");
QMenu* menu2 = new QMenu("编辑");
QMenu* menu3 = new QMenu("视图");
menuBar->addMenu(menu1);
menuBar->addMenu(menu2);
menuBar->addMenu(menu3);
// 3.给菜单添加菜单项
QAction* action1 = new QAction("新建");
QAction* action2 = new QAction("打开");
QAction* action3 = new QAction("保存");
QAction* action4 = new QAction("另存为");
QAction* action5 = new QAction("退出");
menu1->addAction(action1);
menu1->addAction(action2);
menu1->addAction(action3);
menu1->addAction(action4);
menu1->addAction(action5);
// 4. 添加信号槽
connect(action1, &QAction::triggered, this, &MainWindow::handle);
connect(action5, &QAction::triggered, this, &MainWindow::close);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::handle()
{
qDebug() << "触发新建操作";
}

- 关键注意点: 菜单栏全局唯一,多次调用
setMenuBar()只会保留最后一个;以及菜单栏的创建方式注意点


2.2 实战示例2:添加快捷键
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QMenuBar* menuBar = new QMenuBar();
this->setMenuBar(menuBar);
QMenu* menu1 = new QMenu("文件 (&F)");
QMenu* menu2 = new QMenu("视图 (&V)");
menuBar->addMenu(menu1);
menuBar->addMenu(menu2);
// 创建四个菜单项
QAction* action1 = new QAction("action1 (&Q)");
QAction* action2 = new QAction("action2 (&W)");
QAction* action3 = new QAction("action3 (&E)");
QAction* action4 = new QAction("action4 (&R)");
menu1->addAction(action1);
menu1->addAction(action2);
menu2->addAction(action3);
menu2->addAction(action4);
// 不绑定槽函数,有快捷键也没啥显示
connect(action1, &QAction::triggered, this, &MainWindow::handle1);
connect(action2, &QAction::triggered, this, &MainWindow::handle2);
connect(action3, &QAction::triggered, this, &MainWindow::handle3);
connect(action4, &QAction::triggered, this, &MainWindow::handle4);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::handle1()
{
qDebug() << "handle1";
}
void MainWindow::handle2()
{
qDebug() << "handle2";
}
void MainWindow::handle3()
{
qDebug() << "handle3";
}
void MainWindow::handle4()
{
qDebug() << "handle4";
}

- 关键注意点:
- 菜单项
QAction可复用(同时添加到菜单栏和工具栏),无需重复创建(后续会体现); &X格式的菜单名称用于设置Alt+X快捷键(如&F对应Alt+F打开文件菜单);
- 菜单项

2.3 实战示例3:添加子菜单
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QMenuBar* menuBar = new QMenuBar();
this->setMenuBar(menuBar);
QMenu* parentMenu = new QMenu("父菜单");
QMenu* childMenu1 = new QMenu("子菜单1");
QMenu* childMenu2 = new QMenu("子菜单2");
menuBar->addMenu(parentMenu);
parentMenu->addMenu(childMenu1);
parentMenu->addMenu(childMenu2);
QAction* action1 = new QAction("菜单项1");
QAction* action2 = new QAction("菜单项2");
childMenu1->addAction(action1);
childMenu1->addAction(action2);
}
MainWindow::~MainWindow()
{
delete ui;
}


2.4 实战示例4:添加分割线和图标
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// QMenuBar* menuBar = new QMenuBar();
QMenuBar* menuBar = this->menuBar(); // 更标准的写法,防止内存泄露
this->setMenuBar(menuBar);
QMenu* menu = new QMenu("菜单");
// menu->setIcon(QIcon(":/open.png")); // 这个会覆盖文本
menuBar->addMenu(menu);
QAction* action1 = new QAction("菜单项1");
action1->setIcon(QIcon(":/open.png"));
QAction* action2 = new QAction("菜单项2");
action2->setIcon(QIcon(":/save.png"));
menu->addAction(action1);
menu->addSeparator();
menu->addAction(action2);
}
MainWindow::~MainWindow()
{
delete ui;
}

- 关键注意点 :分割线
addSeparator()用于区分不同功能组(如 "保存" 和 "退出" 之间),提升可读性。

三. 工具栏(Tool Bar):常用功能快捷入口
工具栏是菜单栏功能的 "快捷方式集合",通常放置最常用的操作(如新建、保存、复制),支持自定义停靠位置、浮动、移动,可多个共存,灵活适配用户操作习惯。Qt 中通过 QToolBar 类实现,依赖 QAction 作为快捷项。
核心属性与 API:
- 创建方法 :
new QToolBar("工具栏名称", this),通过addToolBar()添加到窗口; - 停靠位置 :
- 创建时指定:
addToolBar(Qt::TopToolBarArea, toolBar)(支持 Top/Bottom/Left/Right 四个方向); - 限制停靠范围:
toolBar->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea);
- 创建时指定:
- 核心属性 :
setFloatable(bool):是否允许浮动(默认 true,浮动时可拖拽为独立窗口);setMovable(bool):是否允许移动(默认 true,关闭后无法调整停靠位置);addAction(action):添加菜单项(复用菜单栏的 QAction,保持功能一致);addWidget(widget):添加自定义控件(如按钮、输入框);
- 分割线 :
addSeparator(),用于区分不同功能组。
3.1 实战示例1:创建工具栏(基本使用)
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QToolBar>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 创建菜单栏
QMenuBar* menuBar = this->menuBar();
this->setMenuBar(menuBar);
// 创建菜单
QMenu* menu = new QMenu("文件");
menuBar->addMenu(menu);
// 工具栏是需要手动创建出来的,自身不会自动创建
QToolBar* toolBar = new QToolBar();
this->addToolBar(toolBar);
// 创建两个菜单项
QAction* action1 = new QAction("保存");
QAction* action2 = new QAction("打开");
// 提示(默认是原来设置的文本)
// action1->setToolTip("点击这里保存文件");
// 图片覆盖文本
action1->setIcon(QIcon(":/save.png"));
action2->setIcon(QIcon(":/open.png"));
// 菜单项设置到工具栏
toolBar->addAction(action1);
toolBar->addAction(action2);
// 菜单项设置到菜单
menu->addAction(action1);
menu->addAction(action2);
connect(action1, &QAction::triggered, this, &MainWindow::handle1);
connect(action2, &QAction::triggered, this, &MainWindow::handle2);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::handle1()
{
qDebug() << "handle1";
}
void MainWindow::handle2()
{
qDebug() << "handle2";
}

- 关键注意点: 菜单项
QAction可复用(同时添加到菜单栏和工具栏),无需重复创建;

3.2 实战示例2:多个工具栏的使用
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QToolBar>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 创建工具栏
QToolBar* toolBar1 = new QToolBar();
QToolBar* toolBar2 = new QToolBar();
// 可以设置初始出现的位置
this->addToolBar(toolBar1);
this->addToolBar(Qt::LeftToolBarArea,toolBar2);
// 设置允许停靠的位置
toolBar2->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);
// 设置不允许浮动
toolBar2->setFloatable(false);
// 设置不允许移动
toolBar2->setMovable(false);
QAction* action1 = new QAction("动作1");
QAction* action2 = new QAction("动作2");
QAction* action3 = new QAction("动作3");
QAction* action4 = new QAction("动作4");
toolBar1->addAction(action1);
toolBar1->addAction(action2);
toolBar2->addAction(action3);
toolBar2->addAction(action4);
}
MainWindow::~MainWindow()
{
delete ui;
}

- 关键注意点:
setMovable(false)会关闭移动功能,此时setAllowedAreas()也会失效,需谨慎使用;- 自定义控件(如按钮、输入框)通过
addWidget()添加,扩展工具栏功能(如搜索、筛选); - 多个工具栏会按添加顺序排列,可通过拖拽调整顺序(默认允许移动时)

四. 状态栏(Status Bar):状态信息展示区域
状态栏位于窗口底部,用于显示三类信息:实时消息(如 "已保存")、永久消息(如版本号)、进度提示(如文件加载进度)。Qt 中通过 QStatusBar 类实现,支持添加标签、进度条等控件,全局唯一。
核心属性与 API:
- 创建方法:
statusBar()(QMainWindow 内置方法,直接获取状态栏对象); - 信息显示 :
- 实时消息:
showMessage("消息内容", 3000)(3000 为显示时长,单位 ms,0 表示永久显示); - 永久消息:
addWidget(label)(左侧添加)、addPermanentWidget(label)(右侧添加,不会被实时消息覆盖);
- 实时消息:
- 核心功能 :
clearMessage()(清空实时消息)、setSizeGripEnabled(false)(关闭右下角大小调整 grip)。
4.1 实战示例:多功能状态栏(实时消息 + 文本 + 进度条 + 按钮)
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLabel>
#include <QProgressBar>
#include <QPushButton>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 存在就获取, 不存在就创建
QStatusBar* statusBar = this->statusBar();
// 如果已经存在,这样设置没有啥意义,但是也不影响
this->setStatusBar(statusBar);
// 放置一个临时信息
// statusBar->showMessage("这是一个临时信息", 3000);
// 放置一些控件
QLabel* label = new QLabel("这是一个Label");
statusBar->addWidget(label); // 从左往右添加
QProgressBar* progressBar = new QProgressBar();
progressBar->setRange(0, 100);
progressBar->setValue(50);
statusBar->addWidget(progressBar);
QPushButton* pushButton = new QPushButton("按钮");
statusBar->addPermanentWidget(pushButton); // 从右往左添加
}
MainWindow::~MainWindow()
{
delete ui;
}

- 关键注意点:
- 状态栏全局唯一,
addPermanentWidget()添加的控件会固定在右侧,不会被showMessage()的实时消息覆盖; - 进度条等动态控件默认隐藏,需要时显示,避免占用状态栏空间;
- 实时消息的显示时长单位为毫秒(ms),0 表示永久显示,需手动调用
clearMessage()清空; - 状态栏高度默认固定,添加的控件需注意尺寸,避免超出状态栏范围。
- 状态栏全局唯一,

五. 浮动窗口(Dock Widget):辅助功能承载区域
浮动窗口(铆接部件)是可浮动、可停靠的辅助窗口,通常位于中心部件周围,用于承载辅助功能(如日志输出、属性设置、文件列表)。它支持拖拽停靠到窗口边缘或浮动为独立窗口,Qt 中通过 QDockWidget 类实现,可多个共存。
核心属性与 API:
- 创建方法 :
new QDockWidget("浮动窗口名称", this),通过addDockWidget()添加到窗口; - 停靠位置 :
addDockWidget(Qt::RightDockWidgetArea, dockWidget)(支持 Top/Bottom/Left/Right 四个方向); - 限制停靠范围 :
setAllowedAreas(Qt::RightDockWidgetArea | Qt::LeftDockWidgetArea);
核心属性 :setFloating(false):是否默认浮动(默认 true,false 为停靠状态);setWidget(widget):设置浮动窗口的内部控件(如列表、文本框);setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetClosable):设置支持的功能(移动、关闭、浮动);
- 核心信号 :
topLevelChanged(bool)(浮动 / 停靠状态切换时触发)。
5.1 实战示例:浮动窗口的基本使用
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDockWidget>
#include <QVBoxLayout>
#include <QLabel>
#include <QPushButton>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 给主窗口添加一个子窗口
QDockWidget* dockWidget = new QDockWidget();
this->addDockWidget(Qt::LeftDockWidgetArea, dockWidget);
// 浮动窗口也是可以设置标题的
dockWidget->setWindowTitle("这是浮动窗口");
// 给浮动窗口内部添加一些其他的控件
// 不能直接给这个浮动窗口添加子控件,而是需要创建出一个单独的QWidget
// 把要添加的控件放入其中,然后再设置到dockWidget
QWidget* container = new QWidget();
dockWidget->setWidget(container);
// 创建垂直布局管理器,把布局管理器设置到QWidget中
QVBoxLayout* layout = new QVBoxLayout();
container->setLayout(layout);
// 创建其他控件放入布局管理器中
QLabel* label = new QLabel("这是一个QLabel");
QPushButton* button = new QPushButton("按钮");
layout->addWidget(label);
layout->addWidget(button);
// 设置浮动窗口允许停靠的位置
dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::TopDockWidgetArea);
}
MainWindow::~MainWindow()
{
delete ui;
}


六. 核心组件避坑指南
- 菜单栏 :
- 新建项目时必须选择
QMainWindow作为基类,否则无法使用menuBar()等内置方法; QAction的快捷键需使用QKeySequence类,避免自定义字符串导致快捷键失效。
- 新建项目时必须选择
- 工具栏:
- 禁止移动(
setMovable(false))后,停靠位置也无法调整,需根据需求谨慎设置; - 自定义控件尺寸不宜过大,避免工具栏占用过多窗口空间。
- 禁止移动(
- 状态栏:
addPermanentWidget()添加的控件在右侧,不会被实时消息覆盖,适合放置版本号等永久信息;- 进度条等动态控件需默认隐藏(
progressBar->hide();// 默认隐藏,需要时显示),使用时再显示,避免状态栏杂乱。
- 浮动窗口:
- 必须通过
setWidget()设置内部控件,否则浮动窗口无法正常显示; - 限制停靠范围时,需确保
setMovable(true),否则限制无效。
- 必须通过

结语:
html
🍓 我是草莓熊 Lotso!若这篇技术干货帮你打通了学习中的卡点:
👀 【关注】跟我一起深耕技术领域,从基础到进阶,见证每一次成长
❤️ 【点赞】让优质内容被更多人看见,让知识传递更有力量
⭐ 【收藏】把核心知识点、实战技巧存好,需要时直接查、随时用
💬 【评论】分享你的经验或疑问(比如曾踩过的技术坑?),一起交流避坑
🗳️ 【投票】用你的选择助力社区内容方向,告诉大家哪个技术点最该重点拆解
技术之路难免有困惑,但同行的人会让前进更有方向~愿我们都能在自己专注的领域里,一步步靠近心中的技术目标!
结语:本文完整覆盖了 Qt 主窗口四大核心组件的实战用法,从单独组件创建到综合应用整合,所有代码均可直接运行。这些组件是 Qt 桌面应用的基础,掌握后可快速搭建标准化、专业化的主窗口界面,适配记事本、编辑器、管理工具等各类桌面应用场景。
✨把这些内容吃透超牛的!放松下吧✨ ʕ˘ᴥ˘ʔ づきらど
