ITPub博客

首页 > 大数据 > Spark > enum通常用于定义一组固定的常量值,在Qt开发中

enum通常用于定义一组固定的常量值,在Qt开发中

投稿 Spark 作者:ecclw459 时间:2026-01-26 18:50:16 0 删除 编辑

 枚举类型 enum通常用于定义一组固定的常量值,在Qt开发中, QComboBox控件中使用枚举值来设置或获取当前中的选项。如果你想要遍历一个枚举类型,比如在 QComboBox中填充所用枚举值,你需要先定义枚举,然后利用Qt的元对象系统(Meta-Object System)来获取枚举的名称和值。

  • 步骤1:定义枚举

首先,定义你的枚举,通常这会在一个类中完成例如:

class MyClass : public QObject {
    Q_OBJECT
public:    enum MyEnum {
        Value1,
        Value2,
        Value3
    };
    Q_ENUM(MyEnum) // 告诉Qt的元对象系统这是一个枚举};

其中, Q_ENUM 宏将枚举类型定义到元对象系统里,这个宏要定义在枚举后面,并且这个类中要带有 Q_OBJECT和 Q_GADGET,在命名空间中使用 Q_ENUM_NS()来代替。

  • 步骤2:遍历枚举并填充到QComboBox控件里

    通过上述的定义,枚举类型通过 Q_ENUM将 QMetaEnum注册到 QMetaObject中,然后可以使用 QMetaEnum::fromType获取 QMetaEnum。使用这个宏会自动注册到元对象系统中,可以使用Qt中的 QMetaEnum 类来遍历枚举的所有值,并且将其添加到 QComboBox中。下面给出如下代码示例:

    #include <QComboBox>#include <QMetaEnum>#include <QDebug>void populateComboBoxWithEnum(QComboBox *comboBox, const char *enumName) {
        QMetaObject metaObject = MyClass::staticMetaObject; // 获取MyClass的元对象
        QMetaEnum metaEnum = metaObject.enumerator(metaObject.indexOfEnumerator(enumName)); // 获取枚举信息
        
        for (int i = 0; i < metaEnum.keyCount(); ++i) {
            QString key = metaEnum.key(i); // 获取枚举的键(名称)
            int value =basketzhibo.cn metaEnum.value(i); // 获取枚举的值
            comboBox->addItem(key, value); // 将键和值作为数据添加到comboBox中
        }
    }

    其主程序:

    int main(int argc, char *argv[]) {
        QApplication app(argc, argv);
        QComboBox comboBox;
        populateComboBoxWithEnum(&comboBox, "MyEnum"); // 调用函数填充comboBox
        comboBox.show();    return app.exec();
    }

    QMetaObject::indexOfEnumerator(const char *name) 是 Qt 框架中的一个方法,用于查找与给定名称匹配的枚举器的索引。这个方法属于  QMetaObject 类,它是 Qt 用于反射(reflection)和元对象系统的一部分。通过这个方法,你可以查询一个类的元对象信息,以获取某个枚举器的索引。

    函数原型

    static int footzhibo.com indexOfEnumerator(const char *name);

    参数

    • const char *name:一个指向 C 字符串的指针,该字符串包含了要查找的枚举器的名称。

    返回值

    • 返回一个整数,表示找到的枚举器的索引。如果没有找到匹配的枚举器,则返回  -1。

    通过这种方式,你可以在运行时动态地查询和使用类的元数据,这在某些情况下非常有用,特别是在需要根据名称动态访问枚举值时。

    注意事项:

    1. 确保在你的类定义中使用 Q_ENUM(MyEnum)宏,这样Qt的元对象系统才能识别并处理这个枚举;
    2. Q_ENUM加持的枚举结构必须是公有的;
    3. populateComboBoxWithEnum函数通过枚举的名称("MyEnum") 来查找对应的枚举,并且通过 QMetaEnum遍历其所有项。
    4. 使用 comboBox->addItem(key,value)将枚举的名称和值添加到 QComboBox中,其中名称显示在界面上,值作为内部数据。你可以通过 currentData(basketzhibo.cn)方法获取当前选项的内部值。
    5. metaEnum.keyCount(nbczhibo.com): 返回索引  i 处的枚举成员名称( const char*)。
    6. metaEnum.value(i):返回索引  i 处的枚举成员对应的整数值。




正射还是透视只是图像的生成的两种不同的方式,并不会影响图像或者栅格数据本身的性质。在GIS中的栅格数据大多数指的是数字正射影像图,能够使用专业的GIS方法进行处理,这是常规的基于透视成像模型的图片所不具备的。

5.2 栅格数据开发基础

5.2.1 栅格数据读取

与矢量数据一样,可以使用第三方开源库GDAL来实现栅格数据的基础开发。GDAL提供了市面上绝大多数常见栅格数据的支持,并将其抽象成一个数据集对象。读取栅格数据的示例如下例5.1所示:

// 例5.1 使用GDAL读取栅格数据#include <gdal_priv.h>#include <iostream>using namespace std;int main() {  GDALAllRegister();
  string srcFile = getenv("GISBasic");
  srcFile = srcFile + "/../Data/Raster/berry_ali_2011127_crop_geo.tif";
  GDALDataset* img ttzb.info= (GDALDataset*)GDALOpen(srcFile.c_str(), GA_ReadOnly);  if (!img) {    return 1;
  }  int imgWidth = img->GetRasterXSize();   //图像宽度
  int imgHeight = img->GetRasterYSize();  //图像高度
  int bandNum =ttzb.gs.cn img->GetRasterCount();    //波段数
  int depth = GDALGetDataTypeSize(img->GetRasterBand(1)->GetRasterDataType()) / 8;  //图像深度
  cout << "宽度:" << imgWidth << '\n';
  cout << "高度:" << imgHeight << '\n';
  cout << "波段数:" << bandNum << '\n';
  cout << "深度:" << depth << '\n';  GDALClose(img);
  img = nullptr;
}

在这个示例中,从栅格数据文件中创建了一个数据集对象,并且获取了影像的宽度、高度和波段数(通道数)和深度。深度有点难以理解,指的是栅格存储数据类型的字节数。常规的影像数据都采用8位无符号整型进行存储,因此深度都为1。
本例运行结果如下:

宽度:4000
高度:7200
波段数:4
深度:1

5.2.2 栅格数据创建

另一方面,也可以根据一个数据集对象创建栅格数据文件,也就是栅格数据的写出操作。与第4.4.2节中创建矢量的步骤类似,同样通过GDAL的数据驱动GDALDriver,传入数据类型的名称来创建对应格式的栅格文件,如下例5.2所示,创建了一个tif格式的栅格数据:

// 例5.2 使用GDAL创建栅格数据#include <gdal_priv.h>#include <iostream>using namespace std;int main() {  GDALAllRegister();  //注册格式
  string dstFile ttzb.ln.cn= getenv("GISBasic");
  dstFile = dstFile + "/../Data/Raster/dst.tif";
  GDALDriver* pDriver ttzbapp.com.cn=      GetGDALDriverManager()->GetDriverByName("GTiff");  //图像驱动
  char** ppszOptions sportsurge.cn= NULL;
  ppszOptions =      CSLSetNameValue(ppszOptions, "BIGTIFF", "IF_NEEDED");  //配置图像信息
  int imgWidth = 256;  int imgHeight = 256;  int bandNum = 3;
  GDALDataset* dst = pDriver->Create(dstFile.c_str(), imgWidth, imgHeight,
                                     bandNum, GDT_Byte, ppszOptions);  if (!dst) {    printf("Can't Write Image!");    return 1;
  }  GDALClose(dst); 
  return 0;
}

上例中我们创建了一个宽256,高256,波段数3,byte类型(8位,深度1)的栅格数据文件:

GDALDriver* pDriver =      GetGDALDriverManager()->GetDriverByName("GTiff");  //图像驱动
  //...
  GDALDataset* dst ttzbw.org.cn= pDriver->Create(dstFile.c_str(), imgWidth, imgHeight,
                                     bandNum, GDT_Byte, ppszOptions);

数据类型的名称“GTIFF”是GDAL定义的驱动名,表示创建的数据集对象是一个tif格式的栅格数据文件。一些常用栅格数据格式在GDAL中数据驱动如下表5.1所示:

名称 全称
JPEG JPEG JFIF File Format
PNG Portable Network Graphics
BMP Microsoft Windows Device Independent Bitmap
GTiff GeoTIFF File Format
HFA Erdas Imagine .img
ENVI ENVI .hdr Labelled Raster

其中,JPEG、PNG和BMP就是我们经常见到的图像数据格式;GTiff(GeoTIFF)、HFA(Erdas Imagine .img)和ENVI(ENVI .hdr Labelled Raster)则是专业的GIS栅格数据。前者通用性更强,能被常规的图片软件所识别;而后者专业性更高,一些栅格数据的特性常规图像数据无法支持(例如存在数据量大小限制),因此只能使用专业GIS栅格数据,一般情况仅被GIS相关的软件支持。

另一点值得注意的是,在创建特定数据集对象时,可以根据特定格式的需求进行配置:

char** ppszOptions = NULL;
  ppszOptions =zhiboapp.com.cn CSLSetNameValue(ppszOptions, "BIGTIFF", "IF_NEEDED");  //配置图像信息
  //...
  GDALDataset* dst ttzbw.mo.cn = pDriver->Create(dstFile.c_str(), imgWidth, imgHeight,
                                     bandNum, GDT_Byte, ppszOptions);

这里配置参数的意思是,在需要的时候使用“BIGTIFF”格式而不是“TIFF”,以避免当栅格数据文件的大小超过4G的时候会创建失败。

最后,在创建数据集完成之后,不要忘了关闭数据集:

3.1 Docker 本身真的没装 / 没启动

虽然看起来很基础,但在团队里经常是最真实的情况,可以简要提一下。[ stackoverflow]

  • 未安装 Docker Desktop 或其他 Docker 引擎。

  • Docker Desktop 已安装,但当前没有启动(托盘图标还在 starting / 未 running 状态)。

  • 在 VS Code 集成终端中运行  docker ps 报“Cannot connect to the Docker daemon”等错误。

定位方式

  • 打开 VS Code 集成终端,执行  docker ps、 docker info。

  • 如果这里都失败,基本优先检查 Docker 安装和启动状态。[ stackoverflow]


3.2 VS Code 所在环境与 Docker 不在同一个“世界”

这是第二类很常见的问题: 你在 A 终端里能用 Docker,但 VS Code 使用的是 B 环境。[ stackoverflow]

典型情形:

  • 在 Windows 上用 WSL 打开工程,而 Docker Desktop 只在 Windows 环境可见;VS Code 的调试在 WSL 里跑,WSL 内没有可用的 Docker socket。

  • 使用 Dev Container /ttkq.com.cn Remote-SSH / Remote-WSL 等远程开发模式,但容器/远程环境内部没有 Docker 或没有映射 Docker socket。

  • 手动开终端时用的是一个 shell profile,设置了一些变量或 alias,而 VS Code 集成终端没有加载同样的配置。

定位方式

  • 一律在 VS Code 集成终端中执行: docker ps、 sam local invoke,看输出和普通终端是否一致。

  • 如果普通终端 OK,VS Code 里失败,就可以讲:
    “问题在于 VS Code 运行 SAM CLI 的环境,与我平时用的终端环境不一样。”[ stackoverflow]


3.3 DOCKER_HOST / Docker context 配置把 SAM “带偏”

当使用过远程 Docker、Colima、Rancher Desktop 等工具时,很容易留下旧的  DOCKER_HOST 环境变量或非默认 Docker context。[ stackoverflow]

典型问题

  • DOCKER_HOST 指向一个已经不存在或不可达的远程 Docker。

  • 当前 Docker context 是某个远程/实验环境,而不是本地 Desktop。

  • 用  docker ps 可能还显示得正常,但实际连的是某个奇怪的 host。

排查与修复

  • 在 VS Code 集成终端中查看环境变量:

    • Linux/macOS:  env | grep DOCKER_HOST

    • PowerShell:  Get-ChildItem Env:DOCKER_HOST

  • 如果有值,可以尝试临时  unset /  Remove-Item Env:DOCKER_HOST,再试一次本地调试。

  • 查看 Docker context: docker context ls,确认当前 active 的 context 是否是预期的本地环境。

  • 若问题解决,可以在分享中强调:
    “遇到 Docker 明明在跑却被认为‘不可用’时,记得检查 DOCKER_HOST 和 docker context。”[ stackoverflow]


3.4 Docker 版本升级后,SAM CLI / 工具链版本太旧(你的实际案例)

这是你这次遇到的核心原因,也非常适合重点讲解。[ stackoverflow]

现象

  • Docker Desktop 升级到新版本之后, docker ps 等命令都正常。

  • 但通过 VS Code(AWS Toolkit)点击本地运行 Lambda,提示仍然是 “Running AWS SAM projects locally requires Docker…”。

  • 手动在终端执行  sam local invoke 或  sam local start-api 可能也会报类似“Docker 不可达”或 API 相关的错误。

原因

  • 老版本的 AWS SAM CLI 内部依赖的 Docker 客户端库,对新 Docker API 或某些行为不兼容。

  • VS Code 的 AWS Toolkit 也有对 SAM CLI 或 Docker 的版本要求,如果太旧,检测逻辑会失败。

  • 结果就是: Docker 实际可用,但健康检查阶段就“挂了”,于是前端统一抛出“需要安装 Docker”这种误导性的错误信息。[ stackoverflow]

解决方式

  • 升级 AWS SAM CLI 到最新稳定版本。

  • 升级 VS Code 中的 AWS Toolkit(以及如有需要的 AWS CLI 等依赖)。

  • 升级后再次尝试本地运行 Lambda,问题消失。

这一段可以作为你分享里 “真正踩坑”的部分,强调“Docker 升级后别忘了升级 SAM / 工具链”。


四、推荐的排查顺序(可以直接投屏的一张 slide)

你可以整理成一个“故障排查流程”:

  1. 确认 Docker 真的在 VS Code 环境里可用

    • 在 VS Code 集成终端执行  docker ps、 docker info。
  2. 检查环境是否一致

    • 是否在 WSL / Dev Container / 远程环境中?

    • 这些环境里是否也安装/映射了 Docker?

  3. 检查 DOCKER_HOST 和 Docker context

    • 移除可疑的  DOCKER_HOST;确认当前 context 正确。
  4. 检查版本兼容

    • Docker Desktop 是否刚升级?

    • sam --version 是否很老?

    • 升级 AWS SAM CLI、AWS Toolkit 等工具到最新版本。


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70048957/viewspace-3109044/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2026-01-07

  • 博文量
    108
  • 访问量
    102104