嵌套Q_GADGET场景下readOnGadget读取内部属性值异常
问题根源
- 传入嵌套gadget的指针类型错误:你全局变量
pointer存储的是&p1.p2d,属于P2D**类型(指向P2D指针的指针),但readOnGadget要求传入gadget对象本身的地址,也就是P2D*类型。你把栈上存储指针变量的内存地址当成了P2D对象地址解析,自然读出的是乱码。 - 嵌套gadget指针获取逻辑错误:你硬编码
int(mp.type()) == 1024判断用户类型,且直接用全局固定的pointer传参,没有从当前属性的读取结果中获取实际的P2D对象指针,逻辑存在根本性错误。 - 枚举值未初始化:
Player::m_carType没有赋初始值,输出的是随机垃圾值。
修复方案
首先修改gadgetExplorer逻辑,删除全局指针的使用,直接从属性读取的QVariant中提取嵌套gadget的真实指针:
void gadgetExplorer(void *ptr, const char* s) { qInfo() << "Pointer received is: " << ptr; int typeId = QMetaType::type(s); const QMetaObject *mo = QMetaType::metaObjectForType(typeId); if (!mo) return; qInfo() << "Q_GADGET: " << mo->className(); QMetaProperty mp; for(int i = 1; i < mo->propertyCount(); i++) { mp = mo->property(i); QVariant val = mp.readOnGadget(ptr); qInfo() << "Q_PROPERTY: " << mp.name() << "Value: " << val; // 匹配P2D指针类型,不要硬编码类型值 if (mp.metaType().id() == qMetaTypeId<P2D*>()) { P2D* innerP2d = val.value<P2D*>(); gadgetExplorer(innerP2d, "P2D"); } } }
修改main函数的初始化逻辑,补全枚举值初始化,删除无用的全局指针赋值:
int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); qRegisterMetaType<Player>(); qRegisterMetaType<P2D>(); qRegisterMetaType<P2D*>(); Player p1; p1.setSpeed(30); p1.m_carType = Player::CarType::NO_CAR; // 初始化枚举值 p1.p2d = new P2D(); p1.p2d->setX(10.0); p1.p2d->setY(25.0); gadgetExplorer(&p1, "Player"); qInfo() << "Value of m_x outside funtion :" << p1.p2d->getX(); return a.exec(); }
额外说明:P2D中定义的
Q_PROPERTY(P2D p2d READ getP2D )、Player中定义的Q_PROPERTY(Player player READ getPlayer)属于冗余属性,不会影响运行,不需要可以直接删除。
修复后输出
Pointer received is: 0x7ffdabcdef10 Q_GADGET: Player Q_PROPERTY: m_speed Value: QVariant(int, 30) Q_PROPERTY: m_carType Value: QVariant(Player::CarType, NO_CAR) Q_PROPERTY: p2d Value: QVariant(P2D*, 0x5555abcdef10) Pointer received is: 0x5555abcdef10 Q_GADGET: P2D Q_PROPERTY: m_x Value: QVariant(float, 10) Q_PROPERTY: m_y Value: QVariant(float, 25) Value of m_x outside funtion : 10
内容的提问来源于stack exchange,提问作者Raphael Sauer
相关产品推荐
相关产品推荐

