Qt 学习笔记 4. QByteArray

Posted zll_@

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt 学习笔记 4. QByteArray相关的知识,希望对你有一定的参考价值。

1. hex 概念

Qt 中,hex是指 十六进制数 的表示形式。

可以使用 QString 对象的 toLocal8Bit() 方法将 hex 字符串 转换为 QByteArray 类型的 二进制数据
并可以使用 QByteArray 对象的 toHex() 方法将 二进制数据 转换回 hex 字符串
这些方法通常用于处理 图像音频 文件,以及进行 数字签名 等操作。

以下是一个简单的示例代码:

QByteArray byte_array = 0x12, 0x34, 0x56, 0x78;
QString hex_data = byte_array.toHex();  // 将二进制数据转换为hex字符串
QByteArray decoded_data = QByteArray::fromHex(hex_data.toLocal8Bit());  // 将hex字符串转换为二进制数据

qDebug() << hex_data;  // 输出:12345678
qDebug() << decoded_data; // 输出:"\\x12\\x34\\x56\\x78"

在以上实例中,首先创建了一个 QByteArray 对象,其中保存了四个字节的二进制数据。
然后,使用QByteArray 对象的 toHex() 方法将其转换为 hex 字符串,并设置其为 QString 对象。
接着,使用 QString 对象的 toLocal8Bit() 方法将 hex 字符串转换为 QByteArray 类型的二进制数据,并使用 fromHex() 方法将其还原为原始的二进制数据。
最终,使用 qDebug() 函数分别输出了二进制数据 转换后hex 字符串和 还原后 的二进制数据。

需要注意的是,虽然 hex 字符串使用十六进制数字来表示数据,但是它们的实际大小和原始的二进制数据大小是不同的。
在将 hex 字符串转换回原始的二进制数据时,需要确保使用正确的 编码格式,否则可能会导致解码出错。

2.一些常用于处理 hex 数据的函数

Qt 中,可以使用 hex 字符串来表示 二进制数据hex 字符串 可以通过 QByteArray 对象的 toHex() 方法生成,也可以通过 QByteArray 对象的 fromHex() 方法将 hex 字符串 转换为 二进制数据

以下是一些常用于处理 hex 数据的函数:

  1. QByteArray QByteArray::toHex() const

该函数将当前 QByteArray 对象中的 二进制数据 转换为 hex 字符串,并返回该字符串。
默认情况下,各个字节之间不会添加分隔符,例如"0123456789ABCDEF"。

  1. QByteArray QByteArray::fromHex(const QByteArray &hexEncoded)

该函数将给定的 hex 字符串 转换为 二进制数据,并返回一个新的 QByteArray 对象。
hexEncoded参数指定要转换的 hex 字符串。

  1. bool QByteArray::fromHex(const char *hexEncoded, int len)

该函数将给定长度的 hex 字符串 转换为 二进制数据,并直接写入当前 QByteArray 对象的数据中。
hexEncoded 参数指定要转换的 hex 字符串,len 指定 hex 字符串的长度。
如果转换成功,函数返回 true,否则返回 false

  1. QByteArray QByteArray::fromHex(const QString &hexEncoded)

该函数类似于 QByteArray::fromHex(const QByteArray& hexEncoded),但是可以直接使用 QString 类型的 hex 字符串作为输入。

在使用 hex 字符串 表示 二进制数据 时,通常需要注意以下几点:

  1. 各个字节之间的分隔符QByteArray::toHex() 方法生成的 hex 字符串通常 没有 分隔符,使用时需要根据需要手动添加。

例如,可以使用 QString::split() 方法将 hex 字符串分为每两个字符一组,并使用 QString::join() 方法在每组之间添加空格或其他字符。

  1. 字节顺序:在网络传输和存储过程中,字节顺序可能会被改变。

Qt 提供了一些函数来处理 字节序转换,例如 qFromLittleEndian()qFromBigEndian()qToLittleEndian()qToBigEndian() 等。

  1. 编码格式QByteArray::fromHex() 方法可以 解析 多种编码格式的 hex 字符串,例如 UTF-8Latin-1 等。

在使用该函数时,需要确保使用正确的编码格式。

总之,在使用 hex 字符串表示二进制数据时,需要小心处理各种细节问题,以免出现错误。

Qt学习笔记

Qt学习笔记整理,内容主要包含:

  • QT的概述
  • 创建QT的项目(hello qt)
  • 第一个窗口及窗口属性
  • 第一个按钮
  • 信号与槽机制
  • 带菜单栏的窗口
  • 对话框
  • 布局
  • 常见的控件
  • QT消息机制以及事件
  • 绘图与绘图设备

笔记整理时间:2023年3月24日~2023年3月29日
代码仓库:https://gitee.com/wwyybtt/qt

文章目录

1. Qt概述

1.1 什么是Qt

Qt是一个跨平台C++图形用户界面应用程序框架。它为应用程序开发者提供建立艺术级图形界面所需的所有功能。它是完全面向对象的,很容易扩展,并且允许真正的组件编程。

常见GUI:

  • Qt:支持多平台开发;支持CSS;面向对象特性体现突出;发展趋势良好。
  • MFC:仅在Windows开发;运行效率高;库安全性好。

1.2 Qt的发展史

  • 1991年Qt最早由奇趣科技开发
  • 1996年进入商业领域,它也是目前流行的linux桌面环境KDE的基础
  • 2008年奇趣科技被诺基亚公司收购,Qt称为诺基亚旗下的编程语言
  • 2012年Qt又被 Digia公司收购
  • 2014年4月跨平台的集成开发环境Qt Creator3.1.0发布,同年5月20日配发了Qt5.3正式版,至此Qt实现了对i0S、Android、WP等各平台的全面支持。当前Qt最新版本为5.13.2(2019.12之前)

1.3 支持的平台

  • Windows - XP、Vista、Win7、Win8、Win2008、Win10
  • Uinux/X11 - Linux、Sun Solaris、HP-UX、Compaq Tru64 UNIX、IBM AIX、SGI IRIX、FreeBSD、BSD/OS、和其他很多X11平台
  • Macintosh - Mac 0s x
  • Embedded -有帧缓冲支持的嵌入式Linux平台,Windows CE

1.4 优点

  • 跨平台,几乎支持所有的平台
  • 接口简单,容易上手,学习QT框架对学习其他框架有参考意义。
  • 一定程度上简化了内存回收机制
  • 开发效率高,能够快速的构建应用程序。
  • 有很好的社区氛围,市场份额在缓慢上升。可以进行嵌入式开发。

1.5 成功案例

  • Linux桌面环境KDE
  • Skype 网络电话
  • Google Earth谷歌地图
  • VLC多媒体播放器
  • virtualBox虚拟机软件
  • 咪咕音乐
  • WPS Office
  • 极品飞车

1.6 Qt的下载与安装

下载地址:https://download.qt.io/archive/qt/

安装流程参考:http://t.csdn.cn/sb407

这里以5.13版本为例:

  • 下载对应平台的安装包
    • 我选择的是:qt-opensource-windows-x86-5.13.2.exe
  • 执行安装程序
  • 注册登录账户
  • 选择安装路径
    • 我选择的是:D:\\ProgramFiles\\Qt\\Qt5.13.2
  • 组件选择
    • 预计使用6G左右空间
  • 安装完成

1.7 QtCreator介绍

Qt和QtCreator的区别:

  • Qt:通俗来说,开发工具包
  • QtCreator:集成的编译器,Qt的桌面环境

QtCreator主页面:

  • 欢迎选项
    • 工程:创建工程、打开工程
    • 示例:demo程序,可下载运行研读代码
    • 教程:一般需要翻墙才能看
  • 编辑选项:
    • 编辑项目文件
  • 设计选项:
    • 设计UI
  • Debug选项:
    • 调试
  • 项目设置选项:
    • 一般不设置
  • 帮助选项:
    • 帮助手册
    • 可以查询

2. 创建Qt项目

创建项目的方式:

  • 方式1:欢迎->Projects->New Project
  • 方式2:菜单栏->文件->新建文件或项目

打开项目:

  • 打开之前创建的项目
  • 方式1:欢迎->Projects->Open Project
  • 方式2:菜单栏->文件->打开文件或项目

创建工程时需要注意:

  • 项目名称
    • 一般不要有特殊符号,不要有中文
    • 选择Application->Qt Widgets Application
    • 例:01_demo
  • 创建路径(项目保存路径)
    • 路径不要带中文
    • 更改为:D:\\2021code\\Qt,设置为默认的项目路径
  • 创建类的基类:
    • 三种基类(Base class)
      • QMainWindow:带菜单栏的窗口
      • QWidget:空白窗口
      • QDialog:对话窗口
    • 首次创建项目,我们选择:Details->Base calss->Qwidget;Source file->取消勾选Generate form(即不使用ui)
    • 创建类的时候,类名首字母大写
  • 编译和运行

Qt项目框架及文件介绍:

  • .pro文件:工程文件,是qmake自动生成的用于生产makfile的配置文件
QT       += core gui //包含的模块
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets //大于Qt4版本才包含此模块
CONFIG += c++11
DEFINES += QT_DEPRECATED_WARNINGS //定义编译选项,表示有些功能被标记为过时了,编译器就会发出警告
SOURCES += \\
    main.cpp \\ //源文件
    widget.cpp

HEADERS += \\
    widget.h //头文件
  • main.cpp
#include "widget.h" //Qt中一个类对应一个头文件,类名就是头文件名

#include <QApplication> //Qt系统提供的标准类名声明头文件

int main(int argc, char *argv[])

    QApplication a(argc, argv); //应用程序类(整个后台管理的命脉,处理应用程序的初始化和结束,事件处理调度。注意不管有多少窗口,一个QApplication类就可)
    Widget w; //实例化对象,调用构造函数
    w.show(); //显示图形界面
    return a.exec(); //主事件循环,在exec函数中,Qt接受并处理用户和系统的事件并且将他们传递给适当的窗口控件

  • widget.cpp
#include "widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)



Widget::~Widget()


  • widget.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

class Widget : public QWidget

    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
;
#endif // WIDGET_H

2.1 快捷键

代码自动对齐:Ctrl + i

快速添加/取消注释:Ctrl + /

3. 设置窗口属性

3.1 确定代码书写位置

.pro文件用于生成可执行文件,.main.cpp主函数,widget.cpp类的函数,widget.h类和头文件。

一般情况下,窗口的属性和添加控件、对控件的操作都会在类的构造函数中书写

  • 优点:可以让主程序中无多余代码

3.2 帮助手册如何查看

  • 方法1:帮助->定位到索引->输入要查询的内容
  • 方法2:Assistant,Qt助手

帮助手册如何查看,以QWidget类为例:

  • 索引->对应的类
    • 类的说明:类的头文件、组件、基类、派生类
    • 类的内容(查找函数的途径):公有函数(Public Funcations)、重载公有函数(Reimplemented Public Functions)、公有的槽函数(Public Slots)……
    • 注意:如果有些函数在类中未找到,还可以去基类中查找。

3.3 设置窗口属性及中文乱码解决

中文乱码解决:

  • 在创建项目之前,Qt主界面->工具->选项->文本编辑器->行为->默认编码,选择UTF-8,Apply->OK

设置窗口属性:在widget.cpp中

Widget::Widget(QWidget *parent)
    : QWidget(parent)

    //修改窗口的标题(第一个窗口)
    this->setWindowTitle("第一个窗口");
    //设置窗口的大小,设置完成可以拉伸
    //this->resize(800, 600);
    //设置窗口固定大小,设置完成不可以拉伸
    this->setFixedSize(500, 500);

4. 第一个按钮

新建工程:02_demo

4.1 创建第一个按钮

使用帮助手册查找QPushButton类

  • #include

创建按钮的步骤:

  1. 包含头文件(.cpo)及模块(.pro)
#include <QPushButton>	//.cpp
QT += widgets		//.pro
  1. 调用类的构造函数创建并显示按钮
//创建按钮方式1
QPushButton* button = new QPushButton;
//button->show();//会新开一个窗口显示按钮

//设置按钮的父对象为窗口,使按钮在窗口上显示
button->setParent(this);
  1. 设置按钮的属性
//----------设置按钮的属性
//设置按钮的文字、内容
button->setText("第一个按钮");
//设置按钮的显示位置
button->move(100, 100);
//设置按钮的大小
button->setFixedSize(400, 400);
  1. 创建按钮的第二种方法
//创建按钮方式2
QPushButton* button2 = new QPushButton("第二个按钮", this);
this->resize(600, 400);

创建按钮两种方式的区别:

  • 方式1:窗口默认大小,按钮显示在左上角
  • 方式2:窗口根据按钮的大小来创建,使用方法2,一般还需要调用resize函数重置窗口大小

4.2 对象树(对象模型)

在Qt中创建对象的时候会提供一个Parent对象指针,下面来解释这个parent到底是干什么的。

概念:Qt对象间父子关系。

  • QObject是以对象树的形式组织起来的。
    • 当你创建一个QObject对象时,会看到QObject_的构造函数接收一个QObject指针作为参数,这个参数就是parent,也就是父对象指针。这相当于,在创建QObject对象时,可以提供一个其父对象,我们创建的这个QObject对象会自动添加到其父对象的children()列表。
    • 当父对象析构的时候,这个列表中的所有对象也会被析构。(注意,这里的父对象并不是继承意义上的父类! )
  • QWidget是能够在屏幕上显示的一切组件的父类。
    • QWidget继承自QObject,因此也继承了这种对象树关系。一个孩子自动地成为父组件的一个子组件。因此,它会显示在父组件的坐标系统中,被父组件的边界剪裁。例如,当用户关闭一个对话框的时候,应用程序将其删除,那么,我们希望属于这个对话框的按钮、图标等应该一起被删除。事实就是如此,因为这些都是对话框的子组件。
    • 当然,我们也可以自己删除子对象,它们会自动从其父对象列表中删除。比如,当我们删除了一个工具栏时,其所在的主窗口会自动将该工具栏从其子对象列表中删除,并且自动调整屏幕显示。

解决问题:Qt引对象树的概念,在一定程度上解决了内存问题。

  • 当一个QObject对象在堆上创建的时候,Qt会同时为其创建一个对象树。不过,对象树中对象的顺序是没有定义的。这意味着,销毁这些对象的顺序也是未定义的。
  • 任何对象树中的QObject对象 delete 的时候,如果这个对象有parent,则自动将其从parent 的children()列表中删除;如果有孩子,则自动delete每一个孩子。Qt保证没有QObject会被delete 两次,这是由析构顺序决定的。
  • 如果QObject在栈上创建,Qt保持同样的行为。正常情况下,这也不会发生什么问题。

4.3 对象树使用注意

C++在栈上创建对象时,是后创建的先析构,对于Qt的对象树,有以下需要注意的地方:

// 代码1
QWidget window;
QPushButton button = QPushButton("退出", &window);

// 代码2
QPushButton quit("Quit");
QWidget window;
quit.setParent(&window);
  • 代码1无问题:
    • 因为栈一般先构造的后析构,代码1中执行结束后会先析构button,同时将button从window的子对象列表删除,然后析构window。因为window中已经无button子对象,仅析构window。
  • 代码2有问题:
    • 代码执行结束后会先析构window,而析构window时,会先析构它的子对象quit,然后析构window。接下来会再次析构quit,会导致二次析构,程序崩溃!
  • 如何解决:在Qt中,尽量在构造的时候就指定parent对象,并且大胆地在堆上创建!

4.4 Qt窗口坐标体系

窗口坐标体系:

  • 注意:对于嵌套窗口,其坐标是相对于父窗口来说的。

5. 信号与槽机制

5.1 信号与槽机制介绍

信号槽是Qt 框架引以为豪的机制之一。所谓信号槽,实际就是观察者模式。当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣,它就会使用连接(connect)函数,意思是,将想要处理的信号和自己的一个**函数(称为槽(slot))**绑定来处理这个信号。也就是说,当信号发出时,被连接的槽函数会自动被回调。

  • 这就类似观察者模式:当发生了感兴趣的事件,某一个操作就会被自动触发。
  • 优点:松散耦合,信号发出端和接受端可以毫无关联,如果要关联就用connect函数

5.2 connect函数与系统自带的信号和槽函数

5.2.1 connect函数常用的格式

connect()函数是QObject类中的公有函数,其声明如下:

QMetaObject::Connection connect(const QObject *sender, const char *signal, const char *method, Qt::ConnectionType type = Qt::AutoConnection) const

connect()函数最常用的一般形式:

connect(sender, signal, receiver, slot);
  • sender:发出信号的对象
  • signal:发送对象发出的信号
  • receiver:接收信号的对象
  • slot:接收对象在接收到信号之后所需要调用的函数(槽函数)

5.2.2 系统自带的信号与槽函数

大部分的类都存在槽函数和信号,打开帮助手册,以QWidget为例:

  • Public Slots:公有的槽函数
  • Signals:信号,有时类中没有Signals时,可以查找其基类

5.2.3 实例

要求:创建一个按钮,点击按钮能实现关闭窗口的功能。

新建项目:03_demo

//创建按钮
QPushButton* button = new QPushButton("点击关闭窗口", this);
//重置窗口大小
this->resize(600, 400);

//信号与槽函数
connect(button, &QPushButton::clicked, this, &Widget::close);

5.3 自定义信号和槽

5.3.1 无参的信号与槽

所在项目:03_demo

步骤1:确定场景

  • 老师饿了,学生请客(以这个为例)
  • 小哥敲门,家人开门(自己练习实现)

步骤2:添加老师类和学生类

步骤3:

  • 在老师类中声明信号(声明即可)
    • teacher.h
    • 信号一般在类声明中的signals下写
    • 信号返回值为void,参数可以添加或为空
    • 仅声明,不实现
    • 一般情况下可以重载
  • 并且在学生类中声明槽函数(声明并实现)
    • 在student.h声明
    • 槽函数声明一般在类声明中的public slots下写(对于高版本的Qt,也可以写到public或者全局)
    • 槽函数返回值为void,参数可以添加或者为空
    • 槽函数声明且实现
    • 槽函数定义实现在student.cpp中
//teacher.h
signals:
    void hungury();

//student.h
public slots:
    void treat();

//student.cpp
void Student::treat()
   
    qDebug() << "请吃饭"; //包含头文件:#include <QDebug>

步骤4:创建老师对象和学生对象,并使用connect连接

  • 在widget.cpp中创建并连接
this->tea = new Teacher(this);
this->stu = new Student(this);
connect(tea, &Teacher::hungury, stu, &Student::treat);

步骤5:触发信号

  • widget.h中声明触发信号的成员函数
  • widget.cpp定义触发信号的成员函数
  • 调用该函数
//widget.h
public:
    void ClassOver();

//widget.cpp
void Widget::ClassOver()

    emit tea->hungury();


//调用
ClassOver();

补充:

  • 点击按钮,请老师吃饭
connect(button, &QPushButton::clicked, this, &Widget::ClassOver);

this->tea = new Teacher(this);
this->stu = new Student(this);
connect(tea, &Teacher::hungury, stu, &Student::treat);
  • 信号连接信号
this->tea = new Teacher(this);
this->stu = new Student(this);
connect(tea, &Teacher::hungury, stu, &Student::treat);

connect(button, &QPushButton::clicked, tea, &Teacher::hungury);

5.3.2 重载自定义信号与槽(有参)

步骤1:重新写信号(带参数)

void hungury(QString food);

步骤2:重新写槽函数声明及定义(带参数)

void treat(QString food);

void Student::treat(QString food)

    qDebug() << "请老师吃饭:" << food;

步骤3:由于函数重载了,所以需要利用函数指针指向函数地址,然后再作连接

//定义函数指针
void (Teacher::*teachersignal)(QString) = &Teacher::hungury;
void (Student::*studentslot)(QString) = &Student::treat;

connect(tea, teachersignal, stu, studentslot);
ClassOver();

5.4 信号与槽总结

自定义信号与槽注意事项:

  • 发送者与接受者需要是QObject的子类(槽函数全局,lambda除外)。
  • 信号与槽函数返回值都是void。
  • 信号需要声明,不需要定义实现。槽函数需要声明也需要定义实现。
  • 槽函数是普通的成员函数,作为成员函数,会受到public、private、protected的影响。
  • 使用emit在恰当的位置发送信号。
  • 使用connect()函数连接信号和槽。
  • 任何成员函数、static函数、全局函数和Lambda 表达式都可以作为槽函数。
  • 信号槽要求信号和槽的参数一致,所谓一致,是参数类型一致。
  • 如果信号和槽的参数不一致,允许的情况是,槽函数的参数可以比信号的少,即便如此,槽函数存在的那些参数的顺序也必须和信号的前面几个一致起来。这是因为,你可以在槽函数中选择忽略信号传来的数据(也就是槽函数的参数比信号的少)。

5.5 信号槽的扩展

  • 一个信号可以和多个槽相连
    • 如果是这种情况,这些槽会一个接一个的被调用,但是它们的调用顺序是不确定的。
  • 多个信号可以连接到一个槽
    • 只要任意一个信号发出,这个槽就会被调用。
  • 一个信号可以连接到另外的一个信号
    • 当第一个信号发出时,第二个信号被发出。除此之外,这种信号-信号的形式和信号-槽的形式没有什么区别。
  • 槽可以被断开连接,使用disconnect。
  • 槽也可以被取消连接(当一个对象delete了,就会取消这个对象上的槽)
  • 使用C++11中的lambda表达式

6. Lambda表达式

6.1 Lambda表达式的介绍

概念:C++11中的Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作。

语法:

[capture](parameters) mutable ->return-typestatement;
1[capture]捕获列表,捕获的是那些到定义Lambda为止时Lambda所在作用范围内可见的局部变量
2(parameters)参数列表,与普通函数的参数列表一致的。
3mutable可修改标示符,按值传递捕获列表参数时(默认仅读权限),加上mutable修饰符后,可以修改按值传递进来的拷贝
4->return-type返回值类型
5statement函数体,内容跟普通函数一致
6、分号不能省略

注意:

  • [] 标识一个Lambda的开始,这部分必须存在,不能省略。
  • () 参数列表,如果不需要传递参数的话,()可以一同省略。
  • 如果使用mutable,参数列表 () 不能省略的即使参数为空;如果使用mutable,修改拷贝,而不是值本身。
  • 返回值类型,如果不需要,->return-type都可省略。
  • 函数体,可以使用参数列表,也可以使用捕获列表。

补充:对于捕获列表[]的参数形式,有如下情况

  • 空。没有使用任何函数对象参数。
  • =。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda 所在类的this),并且是值传递方式(相当于编译器自动为我们按值传递了所有局部变量)。
  • &。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的 this),并且是引用传递方式(相当于编译器自动为我们按引用传递了所有局部变量)。
  • this。函数体内可以使用Lambda所在类中的成员变量。
  • a。将a按值进行传递。按值进行传递时,函数体内不能修改传递进来的的拷贝,因为默认情况下函数是const_的。要修改传递进来的a的拷贝,可以添加mutable修饰符。
  • &a。将a 按引用进行传递。
  • a,&b。将a按值进行传递,b按引用进行传递。
  • =,&a,&b。除a和b 按引用进行传递外,其他参数都按值进行传递。
  • &,a, b。除 a和b按值进行传递外,其他参数都按引用进行传递。

6.2 Lambda表达式的使用

一个简单的lambda表达式:

auto fun = []()
    qDebug() << "Lambda is running!";
;

fun();

//
[]
	qDebug() << "Lambda is running!";
();

一个带参数和返回值的lambda:

auto fun = [](int a, int b)
    qDebug() << "Lambda is running!";
    return a + b;
;

int sum = fun(100, 200);
qDebug() << sum;

对于mutable:如果缺少mutable,下列代码将报错;省略()也会报错

    int m = 10;

    auto fun = [m]()mutable
        qDebug() << "Lambda is running!";
        m = 300;
    ;

结合信号与槽:槽函数可以使用lambda,但后面的分号要省略

QPushButton* myBtn = new QPushButton("点击", this);
this->resize(600, 400);

connect(myBtn, &QPushButton::clicked, this, [=]()qDebug() << "按钮被按下";);   //这里的lambda省略了;

7. 带菜单栏的窗口

7.1 QMainWindow概述

QMainWindow是一个为用户提供主窗口程序的类,包含一个菜单栏(menu bar)、多个工具栏(tool bars)、多个铆接部件(dock widgets)、一个状态栏(status bary及一个中心部件(central widget)。

以Qt界面为例,说明各个部件:

  • 铆接部件:浮动窗口
  • 中心部件:写代码的地方

7.2 QMainWindow菜单栏

创建新的项目:04_demo

菜单栏类:QMenuBar

菜单类:QMenu

QAction类:充当子菜单(菜单项)

菜单栏创建方法:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)

    resize(800, 600);

    //创建菜单栏
    QMenuBar* menubar = new QMenuBar(this);//使用new创建
    //QMenuBar* menubar = menuBar();//使用成员函数创建
    this->setMenuBar(menubar);

    //创建菜单
    QMenu* menu1 = new QMenu("文件");
    QMenu* menu2 = new QMenu("编辑");
    QMenu* menu3 = new QMenu("构建");

    //添加菜单到菜单栏
    menubar->addMenu(menu1);
    menubar->addMenu(menu2);
    menubar->addMenu(menu3);

    //创建菜单项/子菜单
    QAction* act1 = new QAction("打开文件");
    QAction* act2 = new QAction("另存为");
    QAction* act3 = 《Qt Quick 4小时入门》学习笔记4

Qt 学习笔记 4. QByteArray

《Qt Quick 4小时入门》学习笔记2

OpenGL学习笔记之坐标变换学习

我的Qt学习笔记 4 如何在 QWidget 窗口上弹出右键菜单

我的Qt学习笔记 4 如何在 QWidget 窗口上弹出右键菜单