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

Qt之QMetaEnum的简单使用(含源码和注释)

文章目录

  • 一、操作示例
  • 二、相关内容的个人理解
  • 三、相关源码
    • mainwindow.h
    • mainwindow.cpp
    • mainwindow.ui
  • 总结

一、操作示例

下方图片未QMetaEnum的部分功能操作示例;枚举名称可选择预先定义准备好的枚举,枚举基础信息枚举属性分别指代枚举相关信息,枚举值操作为枚举字符串与对应数值之间的相互转换操作。
在这里插入图片描述

二、相关内容的个人理解

  1. 枚举名称:枚举名称获取到的数据取决于你在使用QMetaEnum获取枚举对象时使用的枚举名称,可使用在定义枚举时的枚举名称或者通过Q_FLAG修饰符修饰的枚举名称。
  2. 枚举作用域:当前枚举所属的类/对象,
  3. 是否用作标记:要使该属性生效,需要使用Q_DECLARE_FLAGS自定义关键字定义标记宏名称,然后使用Q_FLAG修饰自定义关键字,如下
    // 创建类中的自定义枚举1enum E_ClassEnumOne{eOneFirst = 1,eOneSecond = 10,eOneThird};Q_ENUM(E_ClassEnumOne) // 注册自定义枚举到元数据中,该宏只能在类中使用Q_DECLARE_FLAGS(EnumOneFlag, E_ClassEnumOne); // 使用该宏修饰后,可直接使用修饰的关键字替代对应的枚举名称使用Q_FLAG(EnumOneFlag) // 枚举作为标记的宏定义,使用该宏修饰后,可直接使用 QMetaEnum::fromType<EnumOneFlag>() 获取相应的枚举类型// 标记使用实例// Q_DECLARE_FLAGS通过定义的Flag类型EnumOneFlag oneFlag;// 设置一个默认属性oneFlag.setFlag(eOneSecond);// 分别测试一个已设置和未设置的属性状态qDebug() << oneFlag.testFlag(eOneSecond);qDebug() << oneFlag.testFlag(eOneFirst);
  1. 是否有效:如果此枚举有效(有名称),则返回true;否则返回false。
  2. 是否声明为C++11枚举类:C++11枚举类是指,使用class修饰的枚举,如下
    // 创建类中的自定义枚举2enum class E_ClassEnumTwo{eTwoFirst = 2,eTwoSecond,eTwoThird,eTwoFourth = 40,eTwoFifth,};

三、相关源码

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QMetaEnum>
#include <QDebug>
#include <QAbstractItemModel>// 创全局的自定义枚举
enum E_GlobalEnum
{eGlobalFirst = 2,eGlobalSecond,eGlobalThird
};
Q_DECLARE_FLAGS(EnumGlobalFlag, E_GlobalEnum);namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTpublic:// 创建类中的自定义枚举1enum E_ClassEnumOne{eOneFirst = 1,eOneSecond = 10,eOneThird};Q_ENUM(E_ClassEnumOne) // 注册自定义枚举到元数据中,该宏只能在类中使用Q_DECLARE_FLAGS(EnumOneFlag, E_ClassEnumOne); // 使用该宏修饰后,可直接使用修饰的关键字替代对应的枚举名称使用Q_FLAG(EnumOneFlag) // 枚举作为标记的宏定义,使用该宏修饰后,可直接使用 QMetaEnum::fromType<EnumOneFlag>() 获取相应的枚举类型// 创建类中的自定义枚举2enum class E_ClassEnumTwo{eTwoFirst = 2,eTwoSecond,eTwoThird,eTwoFourth = 40,eTwoFifth,};Q_ENUM(E_ClassEnumTwo) // 注册自定义枚举到元数据中,该宏只能在类中使用public:explicit MainWindow(QWidget *parent = nullptr);~MainWindow();private:/*** @brief initMetaEnumMap 初始化枚举元数据容器*/void initMetaEnumMap();/*** @brief clearWidgetVal 清空控件值*/void clearWidgetVal();/*** @brief enumFlagsTest 自定义枚举Flag对象的测试*/void enumFlagsTest();private slots:/*** @brief on_comboBoxCurEnum_currentIndexChanged 枚举切换下拉框* @param arg1 当前下拉框*/void on_comboBoxCurEnum_currentIndexChanged(const QString &arg1);/*** @brief on_pushButtonStrToVal_clicked 字符串转数值*/void on_pushButtonStrToVal_clicked();/*** @brief on_pushButtonValToStr_clicked 数值转字符串*/void on_pushButtonValToStr_clicked();private:Ui::MainWindow *ui;QMap<QString, QMetaEnum> m_mapMetaEnum; // 存储枚举元数据
};#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"#include <QMetaEnum>
#include <QDebug>MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);initMetaEnumMap();// 枚举标记测试函数enumFlagsTest();
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::initMetaEnumMap()
{// 该行构建报错
//    m_mapMetaEnum["E_GlobalEnum"] = QMetaEnum::fromType<E_GlobalEnum>();m_mapMetaEnum["EnumOneFlag"] = QMetaEnum::fromType<EnumOneFlag>();m_mapMetaEnum["E_ClassEnumOne"] = QMetaEnum::fromType<E_ClassEnumOne>();m_mapMetaEnum["E_ClassEnumTwo"] = QMetaEnum::fromType<E_ClassEnumTwo>();
}void MainWindow::clearWidgetVal()
{// 清空文本框auto listEidt = findChildren<QLineEdit *>();foreach(auto e, listEidt) {e->setText("");}// 清空复选框auto listCheck = findChildren<QCheckBox *>();foreach(auto c, listCheck) {c->setChecked(false);}// 清空下拉框auto listCombo = findChildren<QComboBox *>();listCombo.removeOne(ui->comboBoxCurEnum);foreach(auto c, listCombo) {c->clear();}// 清空枚举值信息框ui->textBrowserVal->clear();
}void MainWindow::enumFlagsTest()
{// Q_DECLARE_FLAGS通过定义的Flag类型EnumOneFlag oneFlag;// 设置一个默认属性oneFlag.setFlag(eOneSecond);// 分别测试一个已设置和未设置的属性状态qDebug() << oneFlag.testFlag(eOneSecond);qDebug() << oneFlag.testFlag(eOneFirst);// Q_DECLARE_FLAGS宏内部为通过typedef关键字的自定义类型QFlags<E_ClassEnumTwo> twoFlag;// 设置一个默认属性twoFlag.setFlag(E_ClassEnumTwo::eTwoFirst, true);qDebug() << twoFlag.testFlag(E_ClassEnumTwo::eTwoFifth);EnumGlobalFlag globalFlag;// 首先输出当前属性是否存在qDebug() << globalFlag.testFlag(eGlobalFirst);// 添加当前属性后再次输出相关属性状态globalFlag.setFlag(eGlobalFirst);qDebug() << globalFlag.testFlag(eGlobalFirst);
}void MainWindow::on_comboBoxCurEnum_currentIndexChanged(const QString &arg1)
{// 清空控件值clearWidgetVal();// 当枚举对象容器不存在当前类型时返回if(!m_mapMetaEnum.contains(arg1)) {return;}const QMetaEnum &metaEnum = m_mapMetaEnum[arg1];// 获取枚举名称ui->lineEditName->setText(QString(u8"enumName: %1  name: %2").arg(metaEnum.enumName(), metaEnum.name()));// 获取枚举名称ui->lineEditKeyCount->setText(QString::number(metaEnum.keyCount()));// 返回枚举的作用域ui->lineEditScope->setText(metaEnum.scope());// 是否用作标记ui->checkBoxFlag->setChecked(metaEnum.isFlag());// 是否有效ui->checkBoxValid->setChecked(metaEnum.isValid());// 是否声明为c++11枚举类ui->checkBoxScoped->setChecked(metaEnum.isScoped());// 根据获取的枚举对象,遍历当前对象的所有值并添加到下拉框中for(int idx = 0; idx < metaEnum.keyCount(); ++idx) {ui->textBrowserVal->append(QString(u8"枚举值文本:%1 枚举值:%2").arg(metaEnum.key(idx)).arg(metaEnum.value(idx)));ui->comboBoxStrToVal->addItem(metaEnum.key(idx));ui->comboBoxValToStr->addItem(QString::number(metaEnum.value(idx)));}
}void MainWindow::on_pushButtonStrToVal_clicked()
{// 当枚举对象容器不存在当前类型时返回if(!m_mapMetaEnum.contains(ui->comboBoxCurEnum->currentText())) {return;}// 获取当前枚举对象const QMetaEnum &metaEnum = m_mapMetaEnum[ui->comboBoxCurEnum->currentText()];// 获取当前文本转换QString keyStr = ui->comboBoxStrToVal->currentText();bool isOk = false;int val = metaEnum.keyToValue(keyStr.toStdString().data(), &isOk);// 转换成功添加到输出框中if(isOk) {ui->textBrowserOutPut->append(QString(u8"字符串 %1 转  值 %2").arg(keyStr).arg(val));}
}void MainWindow::on_pushButtonValToStr_clicked()
{// 当枚举对象容器不存在当前类型时返回if(!m_mapMetaEnum.contains(ui->comboBoxCurEnum->currentText())) {return;}// 获取当前枚举对象const QMetaEnum &metaEnum = m_mapMetaEnum[ui->comboBoxCurEnum->currentText()];// 获取当前值并转换int val = ui->comboBoxValToStr->currentText().toInt();QString keyStr = metaEnum.valueToKey(val);ui->textBrowserOutPut->append(QString(u8"值 %1 转 字符串 %2").arg(val).arg(keyStr));
}

mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"><class>MainWindow</class><widget class="QMainWindow" name="MainWindow"><property name="geometry"><rect><x>0</x><y>0</y><width>564</width><height>671</height></rect></property><property name="windowTitle"><string>MainWindow</string></property><widget class="QWidget" name="centralwidget"><layout class="QVBoxLayout" name="verticalLayout"><item><layout class="QHBoxLayout" name="horizontalLayout_5" stretch="0,1"><item><widget class="QLabel" name="label_6"><property name="text"><string>枚举名称</string></property></widget></item><item><widget class="QComboBox" name="comboBoxCurEnum"><item><property name="text"><string/></property></item><item><property name="text"><string>E_GlobalEnum</string></property></item><item><property name="text"><string>EnumOneFlag</string></property></item><item><property name="text"><string>E_ClassEnumOne</string></property></item><item><property name="text"><string>E_ClassEnumTwo</string></property></item></widget></item></layout></item><item><widget class="QGroupBox" name="groupBox"><property name="title"><string>枚举基础信息</string></property><layout class="QVBoxLayout" name="verticalLayout_3"><item><layout class="QHBoxLayout" name="horizontalLayout_3"><item><widget class="QLabel" name="label_2"><property name="text"><string>枚举名称  </string></property></widget></item><item><widget class="QLineEdit" name="lineEditName"><property name="readOnly"><bool>true</bool></property></widget></item></layout></item><item><layout class="QHBoxLayout" name="horizontalLayout_2"><item><widget class="QLabel" name="label_3"><property name="text"><string>枚举值数量</string></property></widget></item><item><widget class="QLineEdit" name="lineEditKeyCount"><property name="readOnly"><bool>true</bool></property></widget></item></layout></item><item><layout class="QHBoxLayout" name="horizontalLayout"><item><widget class="QLabel" name="label_5"><property name="text"><string>枚举作用域</string></property></widget></item><item><widget class="QLineEdit" name="lineEditScope"><property name="readOnly"><bool>true</bool></property></widget></item></layout></item><item><layout class="QHBoxLayout" name="horizontalLayout_4"><item><widget class="QLabel" name="label_4"><property name="text"><string>枚举值列表</string></property></widget></item><item><widget class="QTextBrowser" name="textBrowserVal"/></item></layout></item></layout></widget></item><item><widget class="QGroupBox" name="groupBox_2"><property name="title"><string>枚举属性</string></property><layout class="QVBoxLayout" name="verticalLayout_2"><item><widget class="QCheckBox" name="checkBoxFlag"><property name="text"><string>是否用作标记</string></property></widget></item><item><widget class="QCheckBox" name="checkBoxValid"><property name="text"><string>是否有效</string></property></widget></item><item><widget class="QCheckBox" name="checkBoxScoped"><property name="text"><string>是否声明为c++11枚举类</string></property></widget></item></layout></widget></item><item><widget class="QGroupBox" name="groupBox_3"><property name="title"><string>枚举值操作</string></property><layout class="QGridLayout" name="gridLayout" columnstretch="1,0" columnminimumwidth="0,0"><item row="1" column="0"><widget class="QComboBox" name="comboBoxValToStr"/></item><item row="0" column="0"><widget class="QComboBox" name="comboBoxStrToVal"/></item><item row="1" column="1"><widget class="QPushButton" name="pushButtonValToStr"><property name="text"><string>数值转字符串</string></property></widget></item><item row="0" column="1"><widget class="QPushButton" name="pushButtonStrToVal"><property name="text"><string>字符串转数值</string></property></widget></item><item row="2" column="0" colspan="2"><widget class="QTextBrowser" name="textBrowserOutPut"/></item></layout></widget></item></layout></widget><widget class="QMenuBar" name="menubar"><property name="geometry"><rect><x>0</x><y>0</y><width>564</width><height>26</height></rect></property></widget><widget class="QStatusBar" name="statusbar"/></widget><resources/><connections/>
</ui>

总结

QMetaEnum类我主要使用文本转枚举值、枚举值转枚举文本的功能,使用改内容可实现在项目中,如遇到多个字符串判断,可使用该字符串转换为枚举值,转if为switch的判断方法。

友情提示——哪里看不懂可私哦,让我们一起互相进步吧
(创作不易,请留下一个免费的赞叭 谢谢 ^o^/)

注:文章为作者编程过程中所遇到的问题和总结,内容仅供参考,若有错误欢迎指出。
注:如有侵权,请联系作者删除

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

相关文章:

  • 标准IO操作
  • Python 常用的正则表达式
  • Redis序列化配置类
  • vue2+elementUI实现园型动态步骤条小组件,带缩放功能
  • 【4】Transformers快速入门:自然语言模型 vs 统计语言模型
  • 【无标题】centos 配置阿里云的yum源
  • vue文件或文件夹拖拽上传
  • WPS文字和Word:不只是表格,段落也可以排序
  • 校园快递小程序(腾讯地图API、二维码识别、Echarts图形化分析)
  • 【Dify学习笔记】:Dify搭建图片文件数据分析助手
  • Kimi K2 架构深度解析:万亿MoE模型的效率革命与智能体突破
  • Linux文件系统:从虚拟接口到物理实现的架构解析
  • 【C++】5. 内存管理
  • Android Studio注释如何不从行首开始
  • gpt-5与gpt-5-fast
  • CPPIO流
  • Postman接口测试:postman设置接口关联,实现参数化
  • 当多模态大语言模型遇上视觉难题!AI视觉探索之旅
  • 视频输入输出模块介绍和示例
  • 编译 BusyBox for ARM 平台
  • 力扣面试150题--爬楼梯 打家劫舍 零钱兑换 最长递增子序列
  • Elasticsearch JS 自定义 ConnectionPool / Connection / Serializer、敏感信息脱敏与 v8 平滑迁移
  • 01-Ansible 自动化介绍与使用
  • 83. 删除排序链表中的重复元素
  • Neo4j Cypher
  • Fiddler国内中文网使用经验分享,从抓包入门到API调试进阶
  • 【读代码】深度解析 Researcher:开源自动化科研助手
  • K8S 节点初始化一键脚本(禁用 SELinux + 关闭 swap + 开启 ipvs 亲测实用)
  • Golang 语言中 Context 的使用方式
  • 计算机视觉(6)-自动驾驶感知方案对比