[Development] Qml/JS QVariantMap conversion problem

Nils Jeisecke jeisecke at saltation.de
Wed Sep 24 19:02:32 CEST 2014


Hi!

While porting to Qt5 I've stumbled over a very strange problem.

QVariantMap objects mutate when transported from C++ via Qml back to C++.

QVariant as constructed on the C++ side:
QVariant(QVariantMap, QMap(("x", QVariant(QStringList, ("a", "b")) ) ) )

QVariant when gone through Qml and handled back to C++:
QVariant(QVariantMap, QMap(("x", QVariant(QVariantMap, QMap(("0",
QVariant(QString, "a") ) ( "1" , QVariant(QString, "b") ) ) ) ) ) )

So what used to be a QStringList now is a QMap?

This is:
a) not the behavior of Qt4/QtQuick 1
b) pretty weird

This does not happen if a QVariant directly wrapping a QStringList is
used, only when a QVariantMap is involved.

Testcase:

--main.cpp--

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QDebug>

class Dummy : public QObject
{
  Q_OBJECT
public:
  Dummy(QObject *parent = 0) : QObject(parent) {}

  Q_INVOKABLE void setMap(const QVariant &map)  {
    qDebug() << "setMap" << map;
  }

  Q_INVOKABLE QVariant buildMap() const {
    QVariantMap map;
    map["x"] = QStringList() << "a" << "b";
    qDebug() << "buildMap" << QVariant(map);
    return map;
  }
};

int main(int argc, char *argv[])
{
  QApplication app(argc, argv);
  QQmlApplicationEngine engine;

  engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

  Dummy *dummy = new Dummy;
  engine.rootContext()->setContextProperty("dummy", dummy);

  return app.exec();
}
#include "main.moc"

--main.qml--

import QtQuick 2.3
import QtQuick.Controls 1.2

ApplicationWindow {
    visible: true
    width: 640
    height: 480

    Button {
      text: "Mutate!"
      onClicked: dummy.setMap(dummy.buildMap());
    }
}

--------------------

Any ideas?

Thanks,

Nils



More information about the Development mailing list