11
#include <QtCore/QCoreApplication>
#include <QVariant>
#include <QtDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QVariantMap map;
    map["foo"] = QVariant(QVariantMap());
    map["baz"] = "asdf";
    qvariant_cast<QVariantMap>(map["foo"])["bar"] = "a";

    qDebug() << qvariant_cast<QVariantMap>(map["foo"])["bar"].toString();
    qDebug() << map["baz"].toString();

    return a.exec();
}

ネストされた QVariantMap 内の QVariant に割り当てようとしています。最初の qDebug() は何も出力しませんが、2 番目は期待どおり "asdf" を出力します。ネストされた変数マップの「バー」キーを値に割り当てるにはどうすればよいですか?

4

5 に答える 5

12

問題は、qvariant_cast が動作している QVariant の内部への参照を返さないことです。コピーを返します。そのため、最上位マップの「foo」要素を新しい子マップで上書きすると、コードは適切に機能します。

#include <QtCore/QCoreApplication>
#include <QVariant>
#include <QtDebug>

int main(int argc, char** argv)
{
    QCoreApplication a(argc, argv);
    QVariantMap map;
    map["foo"] = QVariant(QVariantMap());
    map["baz"] = "asdf";

    QVariantMap newMap;
    newMap["bar"] = "a";
    map["foo"] = QVariant(newMap);

    qDebug() << qvariant_cast<QVariantMap>(map["foo"])["bar"].toString();
    qDebug() << map["baz"].toString();

    return a.exec();
}

おそらく、上書きするのではなく、既存のマップを変更する必要があります。これを行うには、既存のマップをコピーし、新しいデータを追加して (ディープ コピーが作成されます)、マップを次のように書き戻します。

QVariantMap existingMap = qvariant_cast<QVariantMap>(map["foo"]);
existingMap["bar"] = "a";
map["foo"] = QVariant(existingMap);

大量のデータを保存することを検討している場合は、QVariant の使用を再検討することをお勧めします。

于 2012-06-18T21:34:54.123 に答える
3

または、トロリーが好まない方法でそれを行うこともできます。

#include <QtCore/QCoreApplication>
#include <QVariant>
#include <QtDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QVariantMap map;
    map["foo"] = QVariant(QVariantMap());
    map["baz"] = "asdf";
    static_cast<QVariantMap>(map["foo"].data_ptr())["bar"] = "a";

    qDebug() << qvariant_cast<QVariantMap>(map["foo"])["bar"].toString();
    qDebug() << map["baz"].toString();

    return a.exec();
}

または、QVariantMap を直接使用する代わりに、QExplicitlySharedDataPointer を使用して、すべて安全かつ適切に行うこともできます。このような:

#include <QtCore>
#include <QtDebug>
class VarMap : public QVariantMap, public QSharedData {};
typedef QExplicitlySharedDataPointer<VarMap> SharedVarMap;
Q_DECLARE_METATYPE(SharedVarMap)
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QVariantMap map;
    map["foo"] = SharedVarMap(new VarMap());
    map["baz"] = "asdf";
    map["foo"].value<SharedVarMap>()->["bar"] = "a";

    qDebug() << map["foo"].value<SharedVarMap>()->["bar"].toString();
    qDebug() << map["baz"].toString();

    return a.exec();
}
于 2012-08-28T12:49:21.963 に答える
2
template <typename T>
inline T& getStoredValueRef(QVariant &v)
{
    const auto type = qMetaTypeId<T>(static_cast<T*>(nullptr));
    auto& d = v.data_ptr();
    if (type == d.type)
    {
        auto data = reinterpret_cast<T*>(d.is_shared ? d.data.shared->ptr : &d.data.ptr);
        return *data;
    }
    throw std::runtime_error("Bad type");
}

として使用します

(getStoredValueRef<QVariantMap>(map["foo"]))["bar"] = "a";

そしてもっと深く

(getStoredValueRef<QVariantMap>(
    (getStoredValueRef<QVariantMap>(map["foo"]))["bar"]))["zoo"] = "a";
于 2015-03-18T12:32:25.793 に答える