【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中添加头函数声明:

cpp 复制代码
#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的使用:

cpp 复制代码
   //给新增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 的对象树了,意味着后续无法对这个对象进行释放了

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

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

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

所有代码综合

mainwidow.h

cpp 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

public slots:
    void handle();

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

mainwidow.cpp

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的细致内容,早关注不迷路。

相关推荐
南郁2 小时前
007-nlohmann/json 项目应用-C++开源库108杰
c++·开源·json·nlohmann·现代c++·d2school·108杰
菠萝014 小时前
共识算法Raft系列(1)——什么是Raft?
c++·后端·算法·区块链·共识算法
海棠蚀omo4 小时前
C++笔记-C++11(一)
开发语言·c++·笔记
小道士写程序4 小时前
Qt 5.12 上读取 .xlsx 文件(Windows 平台)
开发语言·windows·qt
凌佚5 小时前
rknn优化教程(一)
c++·目标检测·性能优化
Lenyiin7 小时前
《 C++ 点滴漫谈: 四十 》文本的艺术:C++ 正则表达式的高效应用之道
c++·正则表达式·lenyiin
yxc_inspire9 小时前
基于Qt的app开发第十三天
c++·qt·app·tcp·面向对象
虾球xz10 小时前
CppCon 2015 学习:Concurrency TS Editor’s Report
开发语言·c++·学习
潇-xiao10 小时前
Qt 按钮类控件(Push Button 与 Radio Button)(1)
c++·qt
板鸭〈小号〉10 小时前
命名管道实现本地通信
开发语言·c++