Qt MainWindow:主窗口组件的介绍与正确使用

文章目录

      • 一、QMainWindow
      • 二、组件详解
        • [1. 标题栏(Window Title)](#1. 标题栏(Window Title))
        • [2. 菜单栏(Menu Bar)](#2. 菜单栏(Menu Bar))
        • [3. 工具栏(Tool Bar)](#3. 工具栏(Tool Bar))
        • [4. 中心部件(Central Widget)](#4. 中心部件(Central Widget))
        • [5. 停靠窗口(Dock Widget)](#5. 停靠窗口(Dock Widget))
        • [6. 状态栏(Status Bar)](#6. 状态栏(Status Bar))
      • [三、Qt 窗口的关键特性](#三、Qt 窗口的关键特性)

一、QMainWindow

QMainWindow 是⼀个为用户提供主窗⼝程序的类,继承⾃ QWidget 类,并且提供了⼀个预定义的

布局。QMainWindow 包含 ⼀个菜单栏(menu bar)、多个⼯具栏(tool bars)、多个浮动窗口(铆接部件)(dock widgets)、⼀个状态栏(status bar) 和⼀个 中⼼部件(central widget),它内置了标准化的界面结构,无需手动拼接布局,直接适配桌面程序的通用交互逻辑,整体布局分为 6 个核心区域:

复制代码
┌─────────────────────────────────────────────┐
│ 标题栏(Window Title)- 系统自带/Qt 封装    	  │
├─────────────────────────────────────────────┤
│ 菜单栏(Menu Bar)- 顶部固定,文本化功能入口 	  │
├─────────────────────────────────────────────┤
│ 工具栏(Tool Bar)- 菜单栏下,可拖拽快捷按钮      │
├───────────────┬─────────────────────────────┤
│ 停靠窗口       │                             │
│(Dock Widget)  │ 中心部件(Central Widget)    │
│ (侧边面板)    │ (窗口核心内容区,必须设置)	  │
├───────────────┴─────────────────────────────┤
│ 状态栏(Status Bar)- 底部固定,显示状态信息 	  │
└─────────────────────────────────────────────┘

在勾选UI文件创建MainWindow时,QMainWindow必须且自动生成

  1. centralWidget(中心窗口):QMainWindow的核心区域,用于承载主要内容;
  2. menuBar(菜单栏):窗口顶部的默认菜单栏;
  3. statusBar(状态栏):窗口底部的默认状态栏。

这三个组件在 QMainWindow 中只能有一个,无法创建多个,且会直接出现在MainWindow.ui的可视化界面中,同时在编译生成的ui_MainWindow.h里自动生成对应的指针(如ui->centralWidgetui->menuBarui->statusBar)。

二、组件详解

1. 标题栏(Window Title)
  • 位置:窗口最顶部(系统级区域);
  • 功能:显示窗口名称(如"我的Qt应用"),包含系统默认的最小化、最大化/还原、关闭按钮;
  • Qt 控制 :可通过 setWindowTitle("标题") 设置标题,也可自定义标题栏样式(需禁用系统标题栏)。
2. 菜单栏(Menu Bar)

常用函数

函数名 功能说明
addMenu() 向菜单栏添加菜单(支持传标题/图标+标题,或已创建的QMenu对象)
addSeparator() 在菜单栏中添加分隔线(返回对应的特殊QAction)
insertMenu() 在指定Action前插入菜单
clear() 清空菜单栏所有菜单、Action等内容
activeAction() 获取当前高亮的Action
setActiveAction() 设置当前高亮的Action
setNativeMenuBar() 设置是否使用系统原生菜单栏(如macOS顶部全局菜单)
actionAt() 根据坐标获取对应位置的Action
setCornerWidget() 在菜单栏角落(如右上角)设置自定义控件

常用信号

信号名 触发时机
triggered(QAction *) 菜单栏中某个Action被点击时发出
hovered(QAction *) 鼠标悬停到菜单栏的某个Action上时发出

Qt 中的菜单栏是通过 QMenuBar 来实现的。⼀个主窗⼝最多只有⼀个菜单栏 。位于主窗⼝顶

部、主窗⼝标题栏下⾯。

菜单栏的创建:

  • 可以直接通过Qt designer创建:(横向创建QMenu,纵向创建QAction)
  • 也可以通过代码创建菜单栏以及菜单项:
cpp 复制代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //1.创建一个菜单栏
    QMenuBar* menubar=new QMenuBar();
    this->setMenuBar(menubar);

    //2.创建菜单,添加menu
    QMenu* menu1=new QMenu("文件");
    menubar->addMenu(menu1);
    QMenu* menu2=new QMenu("编辑");
    menubar->addMenu(menu2);
    QMenu* menu3=new QMenu("构建");
    menubar->addMenu(menu3);

    //3.给菜单添加菜单项
    QAction* menu1_action1=new QAction("新建文件或项目");
    menu1->addAction(menu1_action1);
    QAction* menu1_action2=new QAction("打开文件或项目");
    menu1->addAction(menu1_action2);
    QAction* menu1_action3=new QAction("最近访问的文件");
    menu1->addAction(menu1_action3);

    //4.绑定信号与槽函数
    connect(menu1_action1,&QAction::triggered,this,&MainWindow::handler);

}

void MainWindow::handler()
{
    qDebug()<<"处理信号";
}

关于QMenuBar的创建:在创建QMainwindow的同时,自动创建了一个QMenuBar,如果直接在堆上开辟并调用 setMenuBar() 会失去对前者的控制,导致内存泄漏,因此推荐使用 QMenuBar* menubar=this -> menuBar(); this->setMenuBar(menubar);来创建

快捷键的设置:

  • 类似于QLabel设置伙伴,在创建菜单栏/菜单项的文本后添加 (&快捷键),可以使用 Alt + 快捷键 选中菜单栏/菜单项。
  • 也可以通过调用 setShortcut 设置快捷键
cpp 复制代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QMenuBar* menubar=new QMenuBar(this);
    this->setMenuBar(menubar);

    QMenu* menu1=new QMenu("文件(&F)");
    menubar->addMenu(menu1);
    QMenu* menu2=new QMenu("编辑(&E)");
    menubar->addMenu(menu2);
    QMenu* menu3=new QMenu("构建(&B)");
    menubar->addMenu(menu3);

    QAction* menu1_action1=new QAction("新建文件或项目(&)");
    menu1->addAction(menu1_action1);
    QAction* menu1_action2=new QAction("打开文件或项目");
    menu1->addAction(menu1_action2);
    QAction* menu1_action3=new QAction("最近访问的文件");
    menu1->addAction(menu1_action3);

 	menu1_action1->setShortcut(QKeySequence(Qt::ControlModifier + Qt::Key_N));
    menu1_action2->setShortcut(QKeySequence(Qt::ControlModifier+Qt::Key_O));
    connect(menu1_action1,&QAction::triggered,this,&MainWindow::handler);

}

子菜单的设置:

cpp 复制代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QMenuBar* menubar=new QMenuBar(this);
    this->setMenuBar(menubar);

    QMenu* menu1=new QMenu("文件(&F)");
    menubar->addMenu(menu1);
    QMenu* menu2=new QMenu("编辑(&E)");
    menubar->addMenu(menu2);
    QMenu* menu3=new QMenu("构建(&B)");
    menubar->addMenu(menu3);
    QMenu* menuchild=new QMenu("子菜单");


    QAction* menu1_action1=new QAction("新建文件或项目");
    menuchild->addAction(menu1_action1);
    QAction* menu1_action2=new QAction("打开文件或项目");
    menuchild->addAction(menu1_action2);
    QAction* menu1_action3=new QAction("最近访问的文件");
    menuchild->addAction(menu1_action3);

    menu1->addMenu(menuchild);//在这里加入到菜单栏
}

添加分割线/菜单栏图标:

cpp 复制代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QMenuBar* menubar=new QMenuBar(this);
    this->setMenuBar(menubar);

    QMenu* menu1=new QMenu("文件(&F)");
    menubar->addMenu(menu1);
    QMenu* menuchild=new QMenu("子菜单");

    menu1->addMenu(menuchild);
    menuchild->setIcon(QIcon(":/favicon.png"));//通过qrc文件导入

    QAction* menu1_action1=new QAction("新建文件或项目");
    menuchild->addAction(menu1_action1);
    menuchild->addSeparator();//注意每次在两个addAciton中间添加分割线
    QAction* menu1_action2=new QAction("打开文件或项目");
    menuchild->addAction(menu1_action2);
    menuchild->addSeparator();//注意每次在两个addAciton中间添加分割线
    QAction* menu1_action3=new QAction("最近访问的文件");
    menuchild->addAction(menu1_action3);
}
3. 工具栏(Tool Bar)

常用函数

函数名 功能说明
addAction() 向工具栏添加动作(支持传文本/图标+文本,或已创建的QAction对象)
addSeparator() 在工具栏中添加分隔线(用于分组Action,返回对应的特殊QAction)
addWidget() 向工具栏添加自定义控件(如QPushButton、QLineEdit、QComboBox等)
setIconSize() 设置工具栏中Action图标的统一尺寸(QSize类型,如QSize(32,32))
setToolButtonStyle() 设置工具栏按钮的显示样式(如仅显示图标、仅显示文本、图标+文本等)
addToolBarBreak() 添加工具栏换行/分隔符(多工具栏并排时,将后续工具栏换到下一行)
setMovable() 设置工具栏是否可拖动(默认可拖动,设为false则固定位置)
setFloatable() 设置工具栏是否可浮动(设为true时,工具栏可拖出成为独立窗口)
clear() 清空工具栏所有Action和自定义控件
actionAt() 根据坐标获取工具栏中对应位置的Action
setVisible() 设置工具栏是否可见(true显示,false隐藏)
toggleViewAction() 返回一个用于控制工具栏显示/隐藏的QAction(常用于菜单中控制工具栏)

常用信号

信号名 触发时机
actionTriggered(QAction *) 工具栏中某个Action被点击/触发时发出
topLevelChanged(bool) 工具栏从"嵌入窗口"变为"浮动窗口"(或反之)时发出,参数表示是否为浮动状态
visibilityChanged(bool) 工具栏显示/隐藏状态改变时发出,参数表示是否可见
movableChanged(bool) 工具栏可拖动状态改变时发出,参数表示是否可拖动
floatableChanged(bool) 工具栏可浮动状态改变时发出,参数表示是否可浮动

创建工具栏,设置图标:

cpp 复制代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
	//QToolBar可以创建多个,且不会自动创建
    QToolBar* toolbar=new QToolBar(this);

    QAction* action1=new QAction("新建文件或项目");
    toolbar->addAction(action1);
    QAction* action2=new QAction("打开文件或项目");
    toolbar->addAction(action2);

    //图标会覆盖文字,设置的文字自动转为tooltip,也可以重新设定tooltip
    action1->setIcon(QIcon(":/gridinsert.png"));
    action2->setIcon(QIcon(":/downline.png"));

    connect(action1,&QAction::triggered,this,&MainWindow::handler);
    connect(action2,&QAction::triggered,this,&MainWindow::handler);
}

在使用过程中 工具栏的QAction也可以添加到QMenuBar中,绑定同一个槽函数,搭配使用

设置停靠位置:

枚举值 功能说明
Qt::LeftToolBarArea 工具栏停靠在窗口左侧
Qt::RightToolBarArea 工具栏停靠在窗口右侧
Qt::TopToolBarArea 工具栏停靠在窗口顶部
Qt::BottomToolBarArea 工具栏停靠在窗口底部
Qt::AllToolBarAreas 工具栏可停靠在以上四个位置
  1. 创建工具栏的同时指定停靠位置;
cpp 复制代码
QToolBar *toolBar1 = new QToolBar(this);
QToolBar *toolBar2 = new QToolBar(this);
// 创建时指定在左侧显示
this->addToolBar(Qt::LeftToolBarArea,toolBar1);
// 创建时指定在右侧显示
this->addToolBar(Qt::RightToolBarArea,toolBar2);
  1. 通过QToolBar类的setAllowedAreas()函数设置。
cpp 复制代码
QToolBar *toolBar1 = new QToolBar(this);
QToolBar *toolBar2 = new QToolBar(this);
this->addToolBar(toolBar1);
this->addToolBar(toolBar2);
// 只允许在左侧停靠
toolBar1->setAllowedAreas(Qt::LeftToolBarArea);
// 只允许在右侧停靠
toolBar2->setAllowedAreas(Qt::RightToolBarArea);

设置浮动属性:

工具栏的浮动属性通过QToolBar类的setFloatable()函数设置:

cpp 复制代码
QToolBar *toolBar1 = new QToolBar(this);
// 设置为浮动
toolBar1->setFloatable(true);

注意区别浮动与拖动的区别:浮动是工具栏可以在桌面任意位置移动,拖动只能停靠在允许停靠的未位置。

4. 中心部件(Central Widget)
  • 位置:窗口中间的核心区域(布局中最大的部分);

  • 核心要求 :QMainWindow 必须设置且只能有一个中心部件,否则窗口会显示异常;

  • 使用示例

    cpp 复制代码
    // 以 QTextEdit 作为中心部件(文本编辑器场景)
    QTextEdit *edit = new QTextEdit(this);
    this->setCentralWidget(edit);
    // 也可嵌套布局(比如放一个 QWidget 包含按钮+表格)
    QWidget *centralWidget = new QWidget(this);
    QVBoxLayout *layout = new QVBoxLayout(centralWidget);
    layout->addWidget(new QPushButton("按钮"));
    layout->addWidget(new QTableWidget);
    this->setCentralWidget(centralWidget);
5. 停靠窗口(Dock Widget)

在 Qt 中,浮动窗⼝也称之为铆接部件。浮动窗⼝是通过 QDockWidget类 来实现浮动的功能 。浮动窗⼝⼀般是位于核⼼部件的周围,可以有多个

常用函数

函数定义 作用说明
QDockWidget(const QString &title, QWidget *parent = nullptr) 创建浮动窗口实例,指定窗口标题和父部件
void setWindowTitle(const QString &title) 设置浮动窗口的标题
QString windowTitle() const 获取浮动窗口当前的标题
void setAllowedAreas(Qt::DockWidgetAreas areas) 设置浮动窗口允许停靠的区域(可通过`
Qt::DockWidgetAreas allowedAreas() const 获取当前设置的允许停靠区域
bool isAreaAllowed(Qt::DockWidgetArea area) const 判断指定的单个区域是否被允许停靠
void setFloating(bool floating) 强制设置窗口的浮动状态(true=悬浮;false=停靠到主窗口)
bool isFloating() const 判断窗口当前是否处于浮动状态
void setWidget(QWidget *widget) 为浮动窗口设置要嵌入的内容控件(QDockWidget作为容器的核心函数)
QWidget *widget() const 获取当前嵌入到浮动窗口中的内容控件
void setTitleBarWidget(QWidget *widget) 替换浮动窗口默认的标题栏为自定义控件
void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget) (QMainWindow的函数)将浮动窗口添加到主窗口的指定初始停靠区域
void QMainWindow::splitDockWidget(QDockWidget *first, QDockWidget *second, Qt::Orientation orientation) (QMainWindow的函数)拆分已有浮动窗口,实现多窗口并列显示

常用信号

信号定义 触发时机
void topLevelChanged(bool floating) 浮动窗口的"浮动/停靠"状态发生变化时触发(如从停靠变悬浮、悬浮变停靠)
void visibilityChanged(bool visible) 浮动窗口的可见性发生变化时触发(如窗口被显示/隐藏)
void allowedAreasChanged(Qt::DockWidgetAreas areas) 浮动窗口允许停靠的区域被修改时触发
void dockLocationChanged(Qt::DockWidgetArea area) 浮动窗口的停靠位置发生变化时触发(如从左侧拖到右侧、顶部拖到底部)
cpp 复制代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
	QDockWidget* dockwidget=new QDockWidget(this);
    //可以使用addDockWidget来指定位置
    this->addDockWidget(Qt::LeftDockWidgetArea,dockwidget);

    //设置标题
    dockwidget->setWindowTitle("dock widget");

    //需要先添加一个widget到dockwidget,再添加子控件到widget
    QWidget* widget=new QWidget();
    dockwidget->setWidget(widget);

    QPushButton* button=new QPushButton(widget);
    button->setGeometry(widget->x(),widget->y(),200,200);

    dockwidget->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::TopDockWidgetArea);
}
6. 状态栏(Status Bar)

重要函数

函数名 功能说明
showMessage 显示临时实时消息,设置timeout(ms)定时消失
addWidget 向状态栏左侧添加普通控件(可被临时消息覆盖)
addPermanentWidget 向状态栏右侧添加永久控件(固定显示,不会被临时消息覆盖)
clearMessage 立即清除当前显示的临时消息
removeWidget 移除已添加到状态栏的控件
currentMessage 获取当前显示的临时消息内容

重要信号

信号名 触发时机
messageChanged 状态栏的临时消息发生变化时触发(包括消息显示、更新、清除)

状态栏是应用程序底部展示简要信息的区域,一个窗口最多仅能包含一个状态栏 。在Qt中,状态栏通过QStatusBar类实现,支持显示三类信息:

  • 实时消息:如当前程序运行状态(会自动消失);
  • 永久消息:如程序版本、机构名称(持续显示);
  • 进度消息:如进度条、百分比提示(展示任务进度)。

状态栏的创建:

通过QMainWindowstatusBar()函数创建状态栏实例,再用setStatusCode()将其挂载到窗口:

cpp 复制代码
 //同样因为ui会自动生成,采用自动生成的,防止内存泄漏
 QStatusBar* statusbar=this->statusBar();
 this->setStatusBar(statusbar);

显示实时消息:

通过showMessage()函数显示临时消息,需指定消息内容和显示时长(单位:毫秒),超时后消息自动消失:

cpp 复制代码
// 在状态栏显示"Hello_Qt",持续2000毫秒(2秒)
statusbar->showMessage("Hello_Qt", 2000);

显示永久消息:

永久消息需通过添加控件(如QLabel)实现,控件会持续显示在状态栏中:

cpp 复制代码
// 1. 创建用于显示永久消息的标签
QLabel *label = new QLabel("提示信息", this);
// 2. 将标签添加到状态栏(默认显示在左侧)
stbar->addWidget(label);

调整永久消息的位置:

若要将控件显示在状态栏右侧 ,需使用addPermanentWidget()函数:

cpp 复制代码
// 创建右侧显示的标签
QLabel *label2 = new QLabel("右侧提示信息", this);
// 将标签固定到状态栏右侧
stbar->addPermanentWidget(label2);

说明:addWidget()默认将控件放在状态栏左侧,addPermanentWidget()固定在右侧,两者可结合使用(如左侧显示提示、右侧显示版本号)。

三、Qt 窗口的关键特性

  1. 布局灵活性 :QMainWindow 的布局是 Qt 预定义的"经典桌面布局",无需手动写复杂的 QLayout 嵌套,直接调用 menuBar()addToolBar()setCentralWidget() 等接口即可;
  2. 组件可定制 :所有组件支持隐藏/显示(比如隐藏工具栏 toolBar->hide()),适配不同场景;
  3. 与 QWidget 的区别
    • QMainWindow:带预设布局,适合做"主窗口"(应用的顶层窗口);
    • QWidget:空白窗口,无预设布局,适合做"子窗口/弹窗/中心部件的子控件"。
相关推荐
oioihoii2 小时前
QT跨平台一次编写,处处编译
开发语言·qt
Macbethad2 小时前
半导体EFEM设备TwinCAT程序设计方案
java·前端·网络
我是一只小青蛙8882 小时前
C++核心过渡:类与对象精讲
开发语言·c++
ggaofeng2 小时前
理解npm的原理
前端·npm·node.js
玖釉-2 小时前
Windows 下 VS2022 编译运行 Khronos Vulkan Samples 全避坑指南
c++·windows·图形渲染
电商API_180079052472 小时前
1688商品详情采集API全解析:技术原理、实操指南与业务落地
大数据·前端·人工智能·网络爬虫
記億揺晃着的那天2 小时前
Chrome 自动填充“用户名”到普通输入框 - 解决方案
前端·chrome
努力学习的小廉2 小时前
【QT(八)】—— 常用控件(五)
开发语言·qt
星火开发设计2 小时前
C++ 分支结构:if-else 与 switch-case 的用法与区别
开发语言·c++·学习·算法·switch·知识·分支