如何使用QMap存储并访问QT自定义图形类数据?
问题解答
一、Ellipse类实现的问题与简化
你当前的实现功能逻辑基本可用,但存在两个明显问题:
- 数据重复存储的隐藏bug:你在Ellipse子类中额外定义了
rad_x/rad_y/start_x/start_y成员变量,仅在构造时赋值,后续调用set方法仅修改基类m_properties,两边数据会出现不一致,完全没必要保留这些冗余成员。 - 基类缺少通用属性读取接口:你的Base类只实现了
setProperty,没有配套的getProperty,导致无法直接从Base指针读取属性。
第一步:先补充Base类的缺失接口
// 在Base类的public区域添加 QVariant getProperty(const QString& key) const { return m_properties.value(key); }
第二步:简化Ellipse类实现
删除Ellipse头文件中自定义的rad_x/rad_y/start_x/start_y成员变量后,cpp代码可以简化为:
#include "ellipse.h" Ellipse::Ellipse(int Start_x, int Start_y, int Rad_x, int Rad_y) { this->setKey("ellipse"); this->setProperty("radX", Rad_x); this->setProperty("radY", Rad_y); this->setProperty("startX", Start_x); this->setProperty("startY", Start_y); } void Ellipse::set_rad_x(int rad_x) { setProperty("radX", rad_x); } void Ellipse::set_rad_y(int rad_y) { setProperty("radY", rad_y); } void Ellipse::set_start_x(int start_x) { setProperty("startX", start_x); } void Ellipse::set_start_y(int start_y) { setProperty("startY", start_y); } int Ellipse::get_rad_x() { return getProperty("radX").toInt(); } int Ellipse::get_rad_y() { return getProperty("radY").toInt(); } int Ellipse::get_start_x() { return getProperty("startX").toInt(); } int Ellipse::get_start_y() { return getProperty("startY").toInt(); }
二、加载数据时的属性访问方案
有两种常用实现方式,根据你的场景选择即可:
方案1:直接用基类通用接口(更适配你当前的设计)
不需要转型,直接调用补充的getProperty方法读取属性:
if(data_storage[t]->key() == "ellipse"){ ui->Ellipse_Value_rad_x->setValue(data_storage[t]->getProperty("radX").toInt()); // 其他属性同理 }
方案2:向下转型为子类指针(适合调用子类独有方法的场景)
用dynamic_cast做安全转型,转型成功后可直接调用子类的自定义方法:
if(data_storage[t]->key() == "ellipse"){ Ellipse* ellipse = dynamic_cast<Ellipse*>(data_storage[t]); if(ellipse) { ui->Ellipse_Value_rad_x->setValue(ellipse->get_rad_x()); // 其他属性同理 } }
三、整体思路优化建议
你当前用m_key标识图形类型的核心思路是可行的,可以做几个小优化降低出错概率:
- 避免硬编码类型字符串:统一定义类型常量,比如
const QString TYPE_ELLIPSE = "ellipse";,所有用到类型匹配的地方都用常量,避免拼写错误。 - 如果后续图形类型、数量较多,遍历QVector匹配key效率低,可以额外维护一个
QMap<QString, QVector<Base*>>的分组存储结构,同类型的图形存在同一个数组中,加载时直接按类型key取对应数组即可,不需要全局遍历。 - 如果你的图形类都需要集成Qt能力,可以让Base类继承QObject,直接用Qt内置的元对象系统读取类名,不需要自己维护
m_key变量,进一步简化代码。
内容的提问来源于stack exchange,提问作者JanJHF
相关产品推荐
相关产品推荐

