2

派生クラスのリストを格納するプロパティを持つ可能性のあるいくつかのQObjectクラスがあります。QListQObject

class Object : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QList<AnotherQObject*> otherObjects READ otherObjects)
public:
    QList<AnotherQObject*> otherObjects() const;
}

QList<AnotherObject*>はもちろん と に登録されていQ_DECLARE_METATYPEますqRegisterMetaType()

このプロパティを Qt のメタ オブジェクト システムで読み取りたいと思います。リストを読みたいと思った時点で、私はリストに から派生したオブジェクトへのポインターが含まれているという事実だけを気にします (そして知っています)QObjectが、正確な型ではありません。

QVariantプロパティをリストに変換するQList<QObject *>と空になります。

QObject *object = getObjectFromSomeWhere();
const char* propertyName = getPropertyNameFromSomeWhere(); // "otherObjects"

QVariant list = object->property(name);
QList<QObject *> objectList = list.value<QList<QObject *> >(); // empty

QList<AnotherQObject*> anotherObjectList = 
    static_cast<Object*>(object)->otherObjects() // not empty

このリストにアクセスできますか? 他の提案はありますか?

編集:私は自分の解決策を投稿しましたが、コメントが大好きです:-)

4

2 に答える 2

2

私はこの問題を非常に最小限に解決したと思います。QVariantを含むをに変換できるテンプレートクラスを作成しましQList<TemplateParameter *>QList<QObject *>

また、対応するコンバーターにQMap<int, Converter *>マップするを格納するシングルトンがあります。QVariant::userType()

これにより、次のようにプロパティに保存する各クラスを登録できます。

VariantToObjectListConverter::instance()->registerConverter<AnotherQObject>();

その後、不明なものに変換できますQVariants

QVariant list = object->property("otherObjects");
QList<QObject *> objects = VariantToObjectListConverter::instance()->convert(variant);

これは必要なコードです:

class ConverterBase
{
public:
    virtual ~ConverterBase() {}
    virtual QList<QObject *> convert(const QVariant &variant) const = 0;
};

template<class Object>
class Converter : public ConverterBase
{
public:
    QList<QObject *> convert(const QVariant &variant) const
    {
        QList<Object *> list = variant.value<QList<Object *> >();
        QList<QObject *> result;
        Q_FOREACH(Object *object, list) result.append(object);
        return result;
    }
};

class VariantToObjectListConverter
{
public:
    Q_GLOBAL_STATIC(VariantToObjectListConverter, instance)

    ~VariantToObjectListConverter()
    {
        QHashIterator<int, ConverterBase *> i(m_converters);
        while (i.hasNext()) {
            i.next();
            delete i.value();
        }
    }

    template<class Object>
    void registerConverter()
    {
        QVariant v = QVariant::fromValue<QList<Object *> >(QList<Object *>());
        m_converters.insert(v.userType(), new Converter<Object>());
    }

    QList<QObject *> convert(const QVariant &variant) const
    {
        ConverterBase *converter = m_converters.value(variant.userType());
        if (!converter)
            return QList<QObject *>();

        return converter->convert(variant);
    }

private:
    QHash<int, ConverterBase *> m_converters;

    VariantToObjectListConverter() {}
};

これで、、、を呼び出すマクロを追加できるようregisterConverter()Q_DECLARE_METATYPEなりqRegisterMetaType()ました。これにより、ユーザーはを呼び出すだけで済みます。

REGISTER_TYPE(TypeName)
于 2013-01-30T11:16:38.770 に答える