当前位置: 首页 > news >正文

【C++ Qt】窗口(Qt窗口框架、菜单栏QMenuBar)


每日激励:“不设限和自我肯定的心态:I can do all things。 — Stephen Curry”

绪论​:
本章来到了Qt常用控件后的第一个新篇章 窗口,本章将通过先总后分的结构带你快速的上手认识QT中的窗口,然后将带你入门窗口中非常常见的菜单栏,主要是通过直接上实践,边实践边学习的方法带你快速学会菜单栏QMenuBar、菜单QMenu、菜单项QAciton,以及其中的许多细节过程附代码和图片,通俗易懂方便观看。后续还将持续更新窗口中的更多内容,敬请期待~
————————
早关注不迷路,话不多说安全带系好,发车啦(建议电脑观看)。

在这里插入图片描述

🦒Qt 中组件的组成框架

如下图为 QMainwindow 中 各组件所处的位置:
在这里插入图片描述
在 Qt 窗⼝ 是通过 QMainWindow类 来实现的

QMainWindow 是⼀个为⽤⼾提供主窗⼝程序的类,继承⾃ QWidget 类,并且提供了⼀个预定义的布局。QMainWindow 包含

  1. ⼀个菜单栏(menu bar)
  2. 多个⼯具栏(tool bars):工具栏本质上就是把菜单中的一些常用的选项直接放到工具栏中方便快捷使用
  3. 多个浮动窗⼝(dock widgets 又称铆接部件 下图箭头所指):或者说成 “子窗口”,如Qt中的如下图,
    在这里插入图片描述
  4. ⼀个 中⼼部件(central widget):窗口最核心的部分:由用户的组件构成,本质在前面已经大致的了解过了,也就是各种常见组件进行排列组合形成的
  5. ⼀个状态栏(status bar):就类似于博客中的文章状态,显示一些信息给用户查看(或者类似记事本状态显示)
    在这里插入图片描述
    再如记事本的状态栏:
    在这里插入图片描述
  • 它是许多应⽤程序的基础,如⽂本编辑器,图⽚编辑器等。

所以通过上面的统一的了解了Qt窗口中的大体构成和框架,下面就将逐一的进行详细的解析。


菜单🍅栏 QMenuBar

  • 首先在一个主窗口最多一个菜单栏

  • Qt 中的菜单栏是通过 QMenuBar 这个类来实现的。⼀个主窗⼝最多只有⼀个菜单栏。位于主窗⼝顶部、主窗⼝标题栏下⾯
    在这里插入图片描述
    其中:菜单QMenu、菜单栏QMenuBar、菜单项QAction(并不是QMenuItem因为此处的菜单项将会和工具栏中使用同一个QAction类,所以就延用工具栏的概念,而工具类似一种动作所以称为QAction)

__
下面将直接通过实操来进行快速的认识和了解,如何搭建一个菜单栏

实操1🎈:

  1. 首先在此处就是创建MainWidow,而不是QWidget文件
  2. 他们创建起来看起来本质和QWidget很像,但是有不同的
    1. ui文件中不一样(下图的 “在这里输入” 本质就是菜单栏)
      在这里插入图片描述

    2. 对象树不一样(自动的多了菜单栏和状态栏)
      在这里插入图片描述

  • 当在菜单栏中输入一个文本时会弹出,也就代表创建了一个新菜单(QMenu)

在这里插入图片描述在这里插入图片描述

  • 当继续在向下填写,就是创建菜单项(QAction)

📖tips:看能会有点bug在添加菜单项时可能无法使用中文(可以通过 cp 拷贝的方式放进去) 新建、保存、另存为
菜单项QAction(相当于菜单项的子项):在这里插入图片描述

创建完后的对象树:

在这里插入图片描述

代码实现🗒️

  1. 创建一个菜单栏 QMenuBar,并设置窗口里面setMenuBar(通过this指针),同样是会放到对象树中的

  2. 创建菜单 QMenu(构造填写可以菜单的名字),再添加到菜单栏中addMenu

  3. 给菜单添加菜单项QAction(构造填写可以菜单项的名字),同样需要添加到菜单中addAction
    在这里插入图片描述

  4. 如何让点击菜单项有反应呢?

    1. 添加信号 triggered 触发,槽函数
  5. 通过connect连接 自定义槽函数 handle

    1. 给新建内部:打印查看即可

mainwidow.h中添加头函数声明:
在这里插入图片描述

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtDebug>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//代码实现//1. 创建菜单栏QMenuBar *bar = new QMenuBar();//2. 将菜单栏添加到对象树中setMenuBar(bar);//3. 创建菜单项QMenu* menu_file =  new QMenu("文件");bar->addMenu(menu_file);QMenu* menu_edit = new QMenu("编辑");bar->addMenu(menu_edit);QMenu* menu_view = new QMenu("视图");bar->addMenu(menu_view);//4. 添加子项QAction* action1 = new QAction("新建");QAction* action2 = new QAction("打开");QAction* action3 = new QAction("保存");QAction* action4 = new QAction("另存为");menu_file->addAction(action1);menu_file->addAction(action2);menu_file->addAction(action3);menu_file->addAction(action4);//5. 添加点击效果//信号槽连接,自定义信号槽connect(action1,&QAction::triggered,this,&MainWindow::handle);
}
void MainWindow::handle()
{qDebug() << "新建!";
}
MainWindow::~MainWindow()
{delete ui;
}

结果:
在这里插入图片描述


再添加点功能:给菜单设置快捷键(如下图)

上图是Windows自带的记事本,其中的如(F)本质就是快捷键:alt + F
所以此处也是学习设置快捷键

实操2🎈

  1. 创建菜单栏QMenuBar、菜单QMenu、菜单项QAction(同上,可以直接使用上述代码)
  2. 快速设置快捷键的方法
    1. &F:在文本中添加 &F 的操作,就添加了快捷键alt + F(如:QMenu(“文件(&F)”))
    2. 此处就设置了文件菜单的快捷键,当然QShortCut(Qt::Key_…)也是能实现的,虽然是&F,但在显示中 & 会被省略

在这里插入图片描述

  1. 给菜单项也添加快捷键同上方法,就略过了~

回顾QShortCut的使用:

   //给新增QAction添加快捷键
1. 创建QShortCut对象:
QShortcut *add = new QShortcut(this);
2. 结合Qt::Key_ ... 快速设置:
add->setKey(Qt::Key_Control + Qt::Key_A);
3. 使用QKeySequence进行间接设置:
add->setKey(QKeySequence("Ctrl+A"));
4. 连接信号槽,进行触发
connect(add,&QShortcut::activated,this,&MainWindow::handle);

结果:
在这里插入图片描述


😎菜单栏中其他细节

QMenu也是提供了addMenu,通过这个操作给某个

  1. 菜单添加子菜单(注意并不是菜单项哈~)

在这里插入图片描述
——
当然还能不断嵌套…

  1. 添加分割线

在QMenu中提供了 addSeparator 这样的函数,调用它会返回一个QAction 对象此时在添加时进行添加即可,其中顺序代表添加到的位置!
在这里插入图片描述

  1. 添加图标
  • 但注意若给QMenu设置图标,QMenu是在QMenuBar上的,此时文本就无法显示了,图标会覆盖文本(空间较少)
  • 使用 QIcon类 + qrc机制管理图片
  • QMenu和QAction中都提供了setIcon,参数需要QICon对象传递进去即可,就能设置图片:

📖tips:若不会QICon+qrc请看blog

在这里插入图片描述

  • 针对QMenuBar的创建细节:
    在这里插入图片描述
    这个代码有些情况下是存在问题的。若创建的项目若勾选了自动生成ui文件就会引起 内存泄漏,因为:

Qt默认会给你生成了一个QMenuBar,当我们设置新的QMenuBar进来的时候,此时就会导致旧的QMenuBar脱离了Qt 的对象树了,意味着后续无法对这个对象进行释放了

  • 但实际上由于现在的计算机内存比较充裕,上述内存泄漏都还好(因为客户端不会像服务器一样需要持续的运行)

所以若要完全避免就需要进行修改,将原本的构造改成:

this->menuBar();
1. 如果QMenuBar操作直接获取
2. 如有QMenuBar不存在就先创建一个新的再返回

在这里插入图片描述

所有代码综合

mainwidow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();public slots:void handle();private:Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

mainwidow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtDebug>
#include <QShortcut>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//代码实现//1. 创建菜单栏QMenuBar *bar = this->menuBar();//2. 将菜单栏添加到对象树中setMenuBar(bar);//3. 创建菜单项QMenu* menu_file =  new QMenu("文件(&F)");bar->addMenu(menu_file);QMenu* menu_edit = new QMenu("编辑(&E)");bar->addMenu(menu_edit);QMenu* menu_view = new QMenu("视图(&V)");bar->addMenu(menu_view);//4. 添加子项QAction* action1 = new QAction("新建");QAction* action2 = new QAction("打开");QAction* action3 = new QAction("保存");QAction* action4 = new QAction("另存为");menu_file->addAction(action1);menu_file->addAction(menu_file->addSeparator());menu_file->addAction(action2);menu_file->addAction(action3);menu_file->addAction(action4);//给新增QAction添加快捷键QShortcut *add = new QShortcut(this);//结合Qt::Key_ ... 快速设置add->setKey(Qt::Key_Control + Qt::Key_A);//使用QKeySequence进行间接设置add->setKey(QKeySequence("Ctrl+A"));connect(add,&QShortcut::activated,this,&MainWindow::handle);//5. 添加点击效果//信号槽连接,自定义信号槽connect(action1,&QAction::triggered,this,&MainWindow::handle);//6. 添加图标QIcon icon_file("\:file.png");QIcon icon_open("\:open.png");QIcon icon_new("\:new.png");QIcon icon_save("\:save.png");menu_file->setIcon(icon_file);action1->setIcon(icon_new);action2->setIcon(icon_open);action3->setIcon(icon_save);}
void MainWindow::handle()
{qDebug() << "新建!";
}
MainWindow::~MainWindow()
{delete ui;
}

本章完。预知后事如何,暂听下回分解。

如果有任何问题欢迎讨论哈!

如果觉得这篇文章对你有所帮助的话点点赞吧!

持续更新大量C++ Qt的细致内容,早关注不迷路。

http://www.xdnf.cn/news/878311.html

相关文章:

  • 高效集成AI能力:使用开放API打造问答系统,不用训练模型,也能做出懂知识的AI
  • Spring MVC 之 异常处理
  • 《一生一芯》数字实验六:实现随机数发生器
  • 联邦学习架构深度分析:支持多家医院协作训练AI模型方案分析
  • Python-多线程
  • 得力Deli GE330W打印机信息
  • 【HW系列】—内网被渗透的解决方案
  • 我也不知道
  • 在C++中,头文件(.h或.hpp)的标准写法
  • 高效使用AI大模型:测试工程师提示词编写框架
  • 小白初学SpringBoot记录
  • LeetCode 热题 100 739. 每日温度
  • 电子电路:空气也会形成电容吗?
  • 修复与升级suse linux
  • 行为型-迭代器模式
  • 检索增强生成(Retrieval-Augmented Generation,RAG)
  • ShardingSphere-JDBC 与 Sharding-JDBC 的对比与区别
  • 【Unity】R3 CSharp 响应式编程 - 使用篇(二)
  • BugKu Web渗透之bp
  • 6个月Python学习计划 Day 14 - 异常处理基础( 补充学习)
  • 制造业数智化:R²AIN SUITE 如何打通提效闭环
  • 苹果企业签名撤销
  • 滑动智能降级:Glide优化加载性能的黑科技
  • Python Day43
  • vue封装gsap自定义动画指令
  • 计算机系统结构-第5章-监听式协议
  • @Minikube安装、配置与应用部署
  • 11. MySQL事务管理(上)
  • C++11新特性(3)
  • Java高级 | 【实验四】Springboot 获取前端数据与返回Json数据