Qt开发⑦Qt的窗口_上_菜单栏+工具栏+状态栏

news/2025/2/26 3:45:56

目录

1. 菜单栏

1.1 创建菜单栏

1.2 在菜单栏中添加菜单

1.3 创建菜单项

1.4 在菜单项之间添加分割线

1.5 添加快捷键

1.6 添加子菜单

1.7 添加图标

1.8 综合示例

2. 工具栏

2.1 创建工具栏

2.2 设置停靠位置

2.3 设置浮动属性 

2.4 设置移动属性

2.5 综合示例

3. 状态栏

3.1 状态栏的创建

3.2 在状态栏中显示实时消息

3.3 在状态栏中显示永久消息

本篇完。


1. 菜单栏

Qt 窗口是通过 QMainWindow类来实现的。

        QMainWindow 是一个为用户提供主窗口程序的类,继承自 QWidget 类,并且提供了⼀个预定义的布局。QMainWindow 包含一个菜单栏(Menu Bar)、多个工具栏(Tool Bars)、多个浮动窗口(铆接部件)(Dock Widgets)、一个状态栏(Status Bar)和一个中心部件(Central Widget),它是许多应用程序的基础,如文本编辑器,图片编辑器等。如下图为 QMainwindow 中各组件所处的位置:


        Qt 中的菜单栏是通过 QMenuBar 这个类来实现的。一个主窗口最多只有一个菜单栏,位于主窗口顶部、主窗口标题栏下面。

菜单栏中包含菜单,菜单中包含菜单项。

1.1 创建菜单栏

(1)方式一

        菜单栏的创建可以借助于 QMainWindow 类提供的 menuBar() 函数来实现。menubar() 函数原型如下:

        如果我们自己创建的项目没有勾选自动生成 ui 文件,那么上述代码是没有问题的。但如果勾选了自动生成 ui 文件(Qt 已经给我们生成了一个 QMenuBar),那么上述代码就会引起内存泄漏。

        程序自己已经创建好了一个 QMenuBar,当设置新的 QMenuBar 进来时,就会导致旧的 QMenuBar 脱离了 Qt 的对象树,意味着后续就无法对这个对象进行释放了。上述程序如果窗口关闭,对象树释放,此时进程就结束了,自然所有的内存都回收给系统,上述内存泄漏也就不会造成影响。但是如果上述代码是出现在一个多窗口的程序中,如果涉及到窗口的频繁跳转切换(窗口的频繁创建销毁),上述内存泄漏就会更严重。但是实际上由于现在的计算机内存比较充裕,上述内存泄漏都还好,但还是要求代码写得更规范一些,所以选中采用下面这种写法。


(2)方式二(更合理的写法)

在堆上动态创建。

如果是获取到已经存在的 QMenuBar,那么这里的设置就是自己替换自己,仍然在对象树上。

使用 setMenuBar 把菜单栏放到窗口中。


1.2 在菜单栏中添加菜单

创建菜单,并通过 QMenu 提供的 addMenu() 函数 来添加菜单。


1.3 创建菜单项

        在 Qt 中,并没有专门的菜单项类,可以通过 QAction 类,抽象出公共的动作,如在菜单中添加菜单项。

QAction 可以给菜单栏使用,也可以给工具栏使用。


1.4 在菜单项之间添加分割线

        在菜单项之间可以添加分割线。分割线如下图所示,添加分割线是通过 QMenu 类提供的 addSeparator() 函数来实现:

示例:


1.5 添加快捷键

在设置菜单的 title 时,在字母前加 & 符号。

效果展示:

先按下 Alt 键,再按 F,其显示的 W 下面会有下划线,表示是有快捷键的,快捷键为 W。


1.6 添加子菜单

  • 菜单栏 -> 菜单 -> 菜单栏
  • 菜单栏 -> 菜单 -> 子菜单 -> 子菜单 -> 菜单栏

QMenu 也提供了 addMenu,通过这个操作可以给某个菜单项添加子菜单。

示例:


1.7 添加图标

按照之前设置图标的方法:

        如果给 QMenu 设置图标。因为当前 QMenu 是长在 QMenuBar 上的,此时文本就不显示,图标会覆盖文本。而 QMenu 是子菜单,图标和文本都是可以显示的。


1.8 综合示例

在窗口上创建一个菜单栏,在菜单栏中添加一些菜单,在某一个菜单中添加一些菜单项。

(1)新建 Qt 项目

注意:此时新建项目时选择的基类 QMainwindow ,如下图示:


(2)在 "mainwindow.cpp" 文件中创建菜单和中央控件

  • 创建一个菜单栏,一个菜单。
  • 两个菜单项:保存,加载。
  • 创建一个 QTextEdit 作为窗口的中央控件。
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    
    // 设置标题
    this->setWindowTitle("我的记事本");
    
    // 创建菜单栏
    QMenuBar* menuBar = new QMenuBar(this);
    this->setMenuBar(menuBar);
    
    // 创建菜单
    QMenu* menu = new QMenu("文件");
    menuBar->addMenu(menu);
    
    // 创建菜单项
    QAction* action1 = new QAction("保存");
    QAction* action2 = new QAction("加载");
    menu->addAction(action1);
    menu->addAction(action2);
    
    // 创建中央控件
    edit = new QTextEdit(this);
    this->setCentralWidget(edit);
    edit->setPlaceholderText("此处编写⽂本内容...");
}

(3)给 action 添加一些动作

// 连接信号槽,点击 action 时触发一定的效果
connect(action1, &QAction::triggered, this, &MainWindow::save);
connect(action2, &QAction::triggered, this, &MainWindow::load);

实现这两个槽函数:

  • 使用 QFileDialog 来实现选择文件的效果
  1. getSaveFileName 用于保存文件的场景,此时的对话框可以输入文件名
  2. getOpenFileName 用于打开文件的场景,此时的对话框可以获取到鼠标选择的文件名
  • 搭配 C++ 标准库的文件操作实现文件读写
void MainWindow::save()
{
    // 弹出对话框,选择写入文件的路径
    QFileDialog* dialog = new QFileDialog(this);
    QString fileName = dialog->getSaveFileName(this, "保存⽂件", "C:/Users/1/");
    qDebug() << "fileName: " << fileName;
    
    // 写⼊⽂件
    std::ofstream file(fileName.toStdString().c_str());
    if (!file.is_open()) {
        qDebug() << "文件保存失败!";
        return;
    }
    const QString& text = edit->toPlainText();
    file << text.toStdString();
    file.close();
}
 
void MainWindow::load()
{
    // 弹出对话框,选择打开的文件
    QFileDialog* dialog = new QFileDialog(this);
    QString fileName = dialog->getOpenFileName(this, "加载文件", "C:/Users/1/");
    qDebug() << "fileName: " << fileName;
    
    // 读取文件
    std::ifstream file(fileName.toStdString().c_str());
    if (!file.is_open()) {
        qDebug() << "文件加载失败!";
        return;
    }
    std::string content;
    std::string line;
    while (std::getline(file, line)) {
        content += line;
        content += "\n";
    }
    file.close();
 
    // 显示到界面上
    QString text = QString::fromStdString(content);
    edit->setPlainText(text);
}

执行程序,可以看到此时就可以通过程序来保存 / 加载文件了,并且对文件进行编辑。


2. 工具栏

        工具栏是应用程序中集成各种功能实现快捷键使用的一个区域。可以有多个,也可以没有,它并不是应用程序中必须存在的组件。它是一个可移动的组件,它的元素可以是各种窗口组件,它的元素通常以图标按钮的方式存在。如下图为工具栏的示意图:


2.1 创建工具栏

        调用 QMainWindow 类的 addToolBar() 函数来创建工具栏,每增加一个工具栏都需要调用一次该函数。

如添加一个工具栏:

工具栏往往是和菜单栏搭配使用的,工具栏中的 QAction 也可以出现在菜单中。

代码示例:

        如果一个 QAction 既是 QMenu 的子元素,又是 QToolBar 的子元素,那么在释放的时候是否会重复 delete 呢?

只会释放一次,不会重复 delete。Qt 内置的机制已经帮我们解决了这个问题。


2.2 设置停靠位置

        工具栏停靠位置的设置有两种方式。一种是在创建工具栏的同时指定停靠的位置,另⼀种是通过 QToolBar 类提供的 setAllowedAreas() 函数来设置。


(1)方式一

创建工具栏的同时指定其停靠的位置。

        在创建工具栏的同时,也可以设置工具栏的位置,其默认位置是在窗口的最上面;如上述代码,默认在最上面显示。工具栏允许停靠的区域由 QToolBar 类提供的 allowAreas() 函数决定,其中可以设置的位置包括:

  • Qt::LeftToolBarArea 停靠在左侧
  • Qt::RightToolBarArea 停靠在右侧
  • Qt::TopToolBarArea 停靠在顶部
  • Qt::BottomToolBarArea 停靠在底部
  • Qt::AllToolBarAreas 以上四个位置都可停靠

示例:


(2)方式二

使用 QToolBar 类提供的 setAllowedAreas()函数 设置停靠位置。

示例:

        说明: 在创建工具栏的同时指定其停靠的位置,指的是程序运行时攻击栏默认所在的位置;而使用  setAllowedAreas() 函数设置停靠位置,指的是攻击栏允许其所能停靠的位置。


2.3 设置浮动属性 

工具栏的浮动属性可以通过 QToolBar 类提供的 setFloatable() 函数来设置。


(1)setFloatable() 函数原型

void setFloatable (bool floatable)


(2)参数

  • true:浮动
  • false:不浮动

(3)示例


2.4 设置移动属性

设置工具栏的移动属性可以通过 QToolBar 类提供的 setMovable() 函数来设置。


(1)setMovable()函数的原型

void setMovable (bool movable)


(2)参数

  • true:移动
  • false:不移动

        说明:若设置工具栏为不移动状态,则设置其停靠位置的操作就不会生效,所以设置工具栏的移动属性类似于总开关的效果。


(3)示例


2.5 综合示例


3. 状态栏

        状态栏是应用程序中输出简要信息的区域。一般位于主窗口的最底部,一个窗口中最多只能有一个状态栏。在 Qt 中,状态栏是通过 QStatusBar 类来实现的。 在状态栏中可以显示的消息类型有:

  • 实时消息:如当前程序状态
  • 永久消息:如程序版本号,机构名称
  • 进度消息:如进度条提示,百分百提示

3.1 状态栏的创建

状态栏的创建是通过 QMainWindow 类提供的 statusBar() 函数来创建。

示例:


3.2 在状态栏中显示实时消息

在状态栏中显示实时消息是通过 showMessage() 函数来实现。

示例:

        通过 showMessage 可以在状态栏中显示一个文本。此时这个文本存在的时间可以自定义,timeout 参数是一个单位为 ms 的时间。如果 timeout 为 0(不填),消息就会持久存在。


3.3 在状态栏中显示永久消息

在状态栏中可以显示永久消息,此处的永久消息是通过标签来显示的。

示例:

显示效果如下:

新增一条显示消息:

展示效果:

新增一个进度条和按钮:

效果展示:


本篇完。

下一篇Qt开发⑧Qt的窗口_下_浮动窗口+对话框。


http://www.niftyadmin.cn/n/5867138.html

相关文章

机器学习数学基础:34.点二列

点二列相关教程 一、点二列相关的定义 点二列相关是一种统计方法&#xff0c;用于衡量两个变量之间的相关程度。在这种相关分析中&#xff0c;一个变量是正态连续性变量&#xff0c;取值可以是连续的数值&#xff0c;比如身高、体重、考试分数等&#xff1b;另一个是真正的二…

Android之图片保存相册及分享图片

文章目录 前言一、效果图二、实现步骤1.引入依赖库2.二维码生成3.布局转图片保存或者分享 总结 前言 其实现在很多分享都是我们自定义的&#xff0c;更多的是在界面加了很多东西&#xff0c;然后把整个界面转成图片保存相册和分享&#xff0c;而且现在分享都不需要第三方&…

【代码随想录】第九章-动态规划(上)

【代码随想录】第九章-动态规划&#xff08;上&#xff09; 第九章 动态规划-上1 斐波那契数列509.斐波那契数列Method1&#xff1a;递归Method2&#xff1a;动态规划 70.爬楼梯746.使用最小花费爬楼梯 2 不同路径62.不同路径63.不同路径II 3 整数拆分343.整数拆分96.不同的二叉…

Unity Shader 学习13:屏幕后处理 - 使用高斯模糊的Bloom辉光效果

目录 一、基本的后处理流程 - 以将画面转化为灰度图为例 1. C#调用shader 2. Shader实现效果 二、Bloom辉光效果 1. 主要变量 2. Shader效果 &#xff08;1&#xff09;提取较亮区域 - pass1 &#xff08;2&#xff09;高斯模糊 - pass2&3 &#xff08;3&#xff…

WordPress R+L Carrier Edition sql注入漏洞复现(CVE-2024-13481)(附脚本)

免责申明: 本文所描述的漏洞及其复现步骤仅供网络安全研究与教育目的使用。任何人不得将本文提供的信息用于非法目的或未经授权的系统测试。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权,请及时与我们联系,我们将尽快处理并删除相关内容。 0x0…

2024/2/23 考试

第一题 One Clue 问题陈述 在数轴上有20000012000001块石头&#xff0c;这些石头的坐标分别为-1000000, -999999, -999998, \ldots, 999999, 1000000−1000000,−999999,−999998,…,999999,1000000。 其中&#xff0c;连续的KK块石头被涂成了黑色&#xff0c;其余的则是白…

C++ day4 练习

一、练习1 找到第一天mystring练习&#xff0c;实现以下功能&#xff1a; mystring str "hello"; mystring ptr "world"; str str ptr; str ptr; str[0] H; 【代码】&#xff1a; #include <iostream> #include <cstring> #include &l…

PHP入门基础学习九(PHP使用手册)

web交互 当表单的method属性提交方式为POST时,浏览器发送POST请求 当表单的method属性提交方式为GET时,浏览器发送GET请求 一、web表单交互 当PHP收到来自浏览器提交的数据后,会自动保存到超全局变量中。 超全局变量是PHP预定义好的变量,可以在PHP脚本的任何位置使用。…