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

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.dtcms.com/a/327017.html

相关文章:

  • [激光原理与应用-253]:理论 - 几何光学 - 变焦镜头的组成原理及图示解析
  • excel-随笔记
  • 单例模式,动态代理,微服务原理
  • [特殊字符]深度解析 FastMCP:重构MCP应用开发的全维度革命
  • 当机械臂装上「智能大脑」:Deepoc具身智能模型如何重构传统自动化​
  • 力扣经典算法篇-50-单词规律(双哈希结构+正反向求解)
  • 【Golang】pprof 使用介绍:从数据采集到可视化分析
  • windows版本:Prometheus+Grafana(普罗米修斯+格拉法纳)监控 JVM
  • Webpack 介绍与使用的详细介绍
  • ChatGpt 5系列文章1——编码与智能体
  • 地图可视化实践录:显示地理区域图
  • 【Bug经验分享】由jsonObject-TypeReference引发的序列化问题
  • 完整多端口 Nginx Docker部署 + GitLab Runner注册及标签使用指南
  • Table Foundation Models: on knowledge pre-training for tabular learning(每日一文)
  • 安卓主题定制实践:17.45MB轻量级主题引擎技术解析
  • Text Animator for Unity快速上手
  • Milvus入门:开源向量数据库,解锁大模型时代的高效检索
  • 面试八股之从jvm层面深入解析Java中的synchronized关键字
  • 【AI绘画】Stable Diffusion webUI 常用功能使用技巧
  • JVM 内存大对象监控和优化实践
  • AT F-Intervals 题解
  • 【KO】大厂常见问题
  • 局域网远程控制/推流
  • 从裸机到云原生:Linux 操作系统实战进阶的“四维跃迁”
  • 嵌入式调试利器:STM32F429移植letter-shell实战
  • 【第四章:大模型(LLM)】05.LLM实战: 实现GPT2-(7)模型训练与微调
  • Apache 服务器基础配置与虚拟主机部署
  • 【自动化备份全网服务器数据项目】
  • 前端,route路由
  • 计算机视觉(7)-纯视觉方案实现端到端轨迹规划(思路梳理)