个人主页Cx330❄️个人专栏《C语言》《LeetCode刷题集》《数据结构-初阶》《C知识分享》《优选算法指南-必刷经典100题》《Linux操作系统》:从入门到入魔《Git深度解析》:版本管理实战全解 《Qt 极境架构》MySQL 核心技术与实战心向往之行必能Cx330的简介目录前言一、 QMainWindow 的整体结构二、 菜单栏 (QMenuBar) 与 菜单项 (QAction)2.1 创建与使用2.2 实战示例1菜单栏 菜单 菜单项的基本使用2.3 实战示例2添加快捷键2.4 实战示例3添加子菜单2.5 实战示例4添加分割线和图标2.6 Qt 对象树与内存管理三. 工具栏Tool Bar常用功能快捷入口3.1 实战示例1创建工具栏(基本使用)3.2 实战示例2多个工具栏的使用四. 状态栏Status Bar状态信息展示区域4.1 实战示例多功能状态栏实时消息 文本 进度条 按钮五. 浮动窗口Dock Widget辅助功能承载区域5.1 实战示例浮动窗口的基本使用六. 核心组件避坑指南前言在 Qt 图形界面开发中QMainWindow是最常用的主窗口基类。它为开发者提供了一个标准的桌面应用程序窗口布局框架。本文将结合实际开发板书系统地讲解QMainWindow的五大构成区域以及QDialog对话框的核心用法。一、 QMainWindow 的整体结构QMainWindow预定义了一套完整的窗口布局结构主要包含以下五个部分-------------------------------------------------- | Menu Bar | -------------------------------------------------- | Tool Bar Area | ------------------------------------------------ | | | | | Dock Widget | Central Widget | Dock Widget | | Area | (核心工作区) | Area | | | | | ------------------------------------------------ | Status Bar | --------------------------------------------------菜单栏 (Menu Bar)位于窗口最上方包含一系列下拉菜单。工具栏 (Tool Bar Area)通常位于菜单栏下方可包含快捷按钮和常用控件支持拖拽停靠。浮动窗口/停靠窗口 (Dock Widget Area)围绕在中心部件周围的停靠面板。核心部件 (Central Widget)窗口中央的主要工作区域如文本编辑器、绘图区等。状态栏 (Status Bar)位于窗口最底部用于显示提示信息或当前状态。提示一个主窗口只能有一个菜单栏和一个状态栏但可以有多个工具栏和浮动窗口。二、 菜单栏 (QMenuBar) 与 菜单项 (QAction)2.1 创建与使用菜单栏通过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(CtrlS))设置快捷键(还有别的方法看下面示例)核心信号QAction::triggered()菜单项被点击时触发。2.2 实战示例1菜单栏 菜单 菜单项的基本使用#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 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.3 实战示例2添加快捷键#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); // 创建4个菜单项 QAction* action1 new QAction(action1(M)); QAction* action2 new QAction(action2(N)); 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格式的菜单名称用于设置AltX快捷键如F对应AltF打开文件菜单2.4 实战示例3添加子菜单#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* menuParent new QMenu(父菜单); QMenu* menuChild new QMenu(子菜单); menuBar-addMenu(menuParent); menuParent-addMenu(menuChild); QAction* action1 new QAction(菜单项1); QAction* action2 new QAction(菜单项2); menuChild-addAction(action1); menuChild-addAction(action2); QMenu* menuChild2 new QMenu(子菜单2); menuChild-addMenu(menuChild2); } MainWindow::~MainWindow() { delete ui; }2.5 实战示例4添加分割线和图标#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* 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-addAction(action2); } MainWindow::~MainWindow() { delete ui; }关键注意点分割线addSeparator()用于区分不同功能组如 “保存” 和 “退出” 之间提升可读性。2.6 Qt 对象树与内存管理在 Qt 中通过QObject的父子关系Object Tree管理对象生命周期当父对象析构时会自动调用所有子对象的析构函数。使用menuBar()或为QMenuBar指定this作为 Parent 时无需手动deleteQt 框架会自动进行内存释放。三. 工具栏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创建工具栏(基本使用)#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)); // 菜单项还可以放到菜单中 menu-addAction(action1); menu-addAction(action2); // 菜单项放到工具栏中 toolBar-addAction(action1); toolBar-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多个工具栏的使用#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 为显示时长单位 ms0 表示永久显示永久消息addWidget(label)左侧添加、addPermanentWidget(label)右侧添加不会被实时消息覆盖核心功能clearMessage()清空实时消息、setSizeGripEnabled(false)关闭右下角大小调整 grip。4.1 实战示例多功能状态栏实时消息 文本 进度条 按钮#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); // 3000ms 后消失 // 给状态栏中添加一个子控件 QLabel* label new QLabel(这是一个QLabel); statusBar-addWidget(label); // QLabel* label2 new QLabel(这是另一个QLabel); // statusBar-addWidget(label2,2); // 2拉伸系数 QProgressBar* progressBar new QProgressBar(); progressBar-setRange(0,100); progressBar-setValue(50); statusBar-addWidget(progressBar); QPushButton* button new QPushButton(按钮); statusBar-addPermanentWidget(button); } MainWindow::~MainWindow() { delete ui; }关键注意点状态栏全局唯一addPermanentWidget()添加的控件会固定在右侧不会被showMessage()的实时消息覆盖进度条等动态控件默认隐藏需要时显示避免占用状态栏空间实时消息的显示时长单位为毫秒ms0 表示永久显示需手动调用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)是否默认浮动默认 truefalse 为停靠状态setWidget(widget)设置浮动窗口的内部控件如列表、文本框setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetClosable)设置支持的功能移动、关闭、浮动核心信号topLevelChanged(bool)浮动 / 停靠状态切换时触发。5.1 实战示例浮动窗口的基本使用#include mainwindow.h #include ui_mainwindow.h #include QDockWidget #include QLabel #include QPushButton #include QVBoxLayout MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui-setupUi(this); // 给主窗口添加一个子窗口 QDockWidget* dockWidget new QDockWidget(); // 使用 addDockWidget 方法吧浮动窗口添加到子窗口中 this-addDockWidget(Qt::LeftDockWidgetArea,dockWidget); // 给浮动窗口设置标题 dockWidget-setWindowTitle(这是一个浮动窗口); // 给浮动窗口内部添加一些其他控件 // 不能直接给这个浮动窗口添加子控件而是需要创建一些单独的 QWidget 把要添加的控件加入到 QWidget // 然后把 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)否则限制无效。