Qt窗口:菜单栏

目录

一、窗口预览

二、菜单栏

快捷键

子菜单

分割线

图标

内存泄露


一、窗口预览

在前面几篇文章中,或者说,Qt初学阶段,接触到的都是QWidget,QWidget指控件,往往作为一个窗口的一部分出现。所谓的窗口,形象的说,就是在Qt Creator中创建项目时,可选项目类型中的MainWindow

Qt的窗口,是通过QMainWindow类实现,继承自QWidget。

下图为QMainWindow中各个部分所在位置。

Menu Bar,粗略的理解。

Tool Bar Area,往往是菜单栏中常用的工具,比如XShell

Dock Widget Area

二、菜单栏

一个窗口只能有一个菜单栏(QMenuBar),一个菜单栏可以有多个菜单(QMenu),一个菜单往往会有多个菜单项(QAction),之所以命名为QAction,是因为工具栏中的多数操作也是菜单栏的快捷方式,统一称QAction。

  • 代码实践

图形化创建菜单很简单,这里不再演示。

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("文件");
    QMenu* menu2= new QMenu("编辑");
    QMenu* menu3= new QMenu("视图");
    QMenu* menu4= new QMenu("关于");
    //菜单栏中加菜单
    menuBar->addMenu(menu1);
    menuBar->addMenu(menu2);
    menuBar->addMenu(menu3);
    menuBar->addMenu(menu4);
    //设置菜单项
    QAction* action1 = new QAction("新建");
    QAction* action2 = new QAction("打开");
    QAction* action3 = new QAction("关闭");
    menu1->addAction(action1);
    menu1->addAction(action2);
    menu1->addAction(action3);

    //菜单项的点击是一个信号,名为触发信号
    connect(action1,&QAction::triggered,this,&MainWindow::handle_create);
    connect(action2,&QAction::triggered,this,&MainWindow::handle_open);
    connect(action3,&QAction::triggered,this,&MainWindow::close);

}
cpp 复制代码
void MainWindow::handle_create()
{
    qDebug() << "新建";
}

void MainWindow::handle_open()
{
    qDebug() << "打开";
}

快捷键

有一种很简单的方式,像下面这样写,比如&F 就等于 添加了Alt + F这样的快捷键。

cpp 复制代码
    QMenu* menu1= new QMenu("文件 (&F)");
    QMenu* menu2= new QMenu("编辑 (&E)");
    QMenu* menu3= new QMenu("视图 (&V)");
    QMenu* menu4= new QMenu("关于 (&A)");
  • QAction绑定快捷键

QAction绑定方式也可以效仿上面那样。

cpp 复制代码
    QAction* action1 = new QAction("新建(&C)");
    QAction* action2 = new QAction("打开(&O)");
    QAction* action3 = new QAction("关闭(&Q)");

运行程序,按下 Alt + F 、C

子菜单

cpp 复制代码
    //添加子菜单
    QMenu* menuChild = new QMenu("子菜单");
    menu1->addMenu(menuChild);
    //给子菜单添加菜单项
    QAction* actionChild = new QAction("菜单项");
    menuChild->addAction(actionChild);

分割线

cpp 复制代码
    menu1->addAction(action1);
    menu1->addSeparator();
    menu1->addAction(action2);
    menu1->addSeparator();
    menu1->addAction(action3);

图标

cpp 复制代码
    QAction* action1 = new QAction("新建(&C)");
    action1->setIcon(QIcon(":/create.jpg"));

也可以给菜单设置图标,只不过QMenu的图标会覆盖文本,而子菜单的图片和文本可以共存。

内存泄露

在上述代码实践中,造成了内存泄露。原因是QMainWindow下,Qt的ui文件会自动生成一个QMenuBar。

而代码中我们是new了一个新的MenuBar,又因为一个窗口只能有一个MenuBar,导致自动生成的MenuBar被new出来的替换,脱离了对象树,造成内存泄露。

解决的办法很简单,保留一个即可,我们在代码中不再new一个新的,而是使用本来就有的。

cpp 复制代码
 //QMenuBar* menuBar = new QMenuBar(this);
    QMenuBar* menuBar = this->menuBar();

这种写法,如果menuBar存在,则直接获取。如果不存在,则新创建一个。

相关推荐
天空'之城1 小时前
单片机基础核心知识点汇总(三十)
单片机·嵌入式硬件
笨笨饿1 小时前
#137_死机恢复现场_Armino平台AP系统swd调试
git·python·stm32·单片机·嵌入式硬件·物联网·vim
linnux领域1 小时前
面包板供电“插哪都不亮“?一个暗断点引发的排查——硬件新手三板斧
单片机·嵌入式硬件·esp32·arduino·面包板·硬件入门
Jaixln_HRF2 小时前
芯维尔CN8010 1.2A/6V同步降压转换器芯片,集成350/230mΩ MOSFET与1.5MHz高频,用于汽车电子/IoT/便携仪器
嵌入式硬件·物联网·硬件工程
yume_sibai2 小时前
03-Rust 函数式编程特性(闭包 + Iterator + Option/Result + 链式调用)
开发语言·后端·rust
xxwxx__2 小时前
深入理解 C++ 继承:从基础语法到底层原理全解析
c++
键盘会跳舞2 小时前
【C++多线程】多线程性能调优:伪共享、缓存行对齐与吞吐优化
c++·多线程·多线程调优
奈斯先生Vector2 小时前
AIGC 视频生成实战:用 Kling Video 拆解文生视频、图生视频与完整工作流
开发语言·人工智能·windows·python·aigc·音视频
小玮看世界2 小时前
[Python]螺旋遍历 vs 最短路径:方向控制类算法的“同源异流”
开发语言·python·算法
学习星球2 小时前
编辑距离——二维 DP 的“最小操作“艺术
c++·leetcode·java-consul