Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: QtScript: Установить значение для свойства QMap
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Script. Интеграция WebKit
shasoft
Создаю свойство типа QMap в объекте, который нужен в qts
Раскрывающийся текст
H
Раскрывающийся текст
    // Узел
    class Osm : public QObject
    {
        Q_OBJECT
        public:
            typedef QMap<QString,QVariant> map;
            map m_nodes;
            Q_PROPERTY(QMap nodes READ getNodes WRITE setNodes)
            map getNodes() const
            {
                return m_nodes;
            }
            void setNodes(map value)
            {
                m_nodes = value;
            }
            //
            QString m_testID;
            //Q_PROPERTY(QString testID READ getTestID WRITE setTestID)
            Q_PROPERTY(QString testID READ getTestID)
            QString getTestID()
            {
                return m_testID;
            }
            void setTestID(QString value)
            {
                m_testID = value;
            }
        public:
            // Конструктор
            Osm(QObject *parent=0);
            // Деструктор
            virtual ~Osm();
            // Инициализация скриптового движка
            static void add(QScriptEngine &engine);
    };

CPP
Раскрывающийся текст
QScriptValue OsmScriptConstructor(QScriptContext *context,
                                  QScriptEngine *engine)
{
    QObject *parent = context->argument(0).toQObject();
    Osm *object = new Osm(parent);
    //-->> Для теста присваиваю эти значения
    object->m_nodes["1111"] = "aaaa";
    object->m_nodes["22222"] = "bbbb";
    //<<--
    return engine->newQObject(object, QScriptEngine::ScriptOwnership,QScriptEngine::ExcludeSuperClassMethods | QScriptEngine::ExcludeSuperClassProperties);
}

// Конструктор
Osm::Osm(QObject *parent) : m_testID("oVo")
{
    qDebug() << "constructor osm::Osm()";
}
Osm::~Osm()
{
    qDebug() << "destructor osm::Osm()";
}
// Инициализация скриптового движка
void Osm::add(QScriptEngine &engine)
{
    //QScriptValue classOsm = engine.scriptValueFromQMetaObject<Osm>();
    QScriptValue ctor = engine.newFunction(OsmScriptConstructor);
    QScriptValue classOsm = engine.newQMetaObject(&QObject::staticMetaObject, ctor);
    engine.globalObject().setProperty("Osm", classOsm);
}



Выполняю такой скрипт
var obj = new Osm()
obj.nodes["333"] = "cccc"
for(var name in obj.nodes)
   print(name,obj.nodes[name])

получаю следующий результат:
Цитата
1111 aaaa
22222 bbbb

Т.е. в сишном коде значения устанавливаются и в скрипте они видны. Но в самом скрипте свойства не устанавливаются. Может кто сталкивался и знает ответ?
Алексей1153
а вот так что выведет ?

var obj = new Osm()
obj.nodes["333"] = "cccc"

print("1111" ,obj.nodes["1111" ])
print("22222",obj.nodes["22222"])
print("333"  ,obj.nodes["333"  ])
shasoft
Цитата
1111 aaaa
22222 bbbb
333 undefined

в общем при том, что новый свойства в скрипте не устанавливаются, этого следовало ожидать
Алексей1153
а я ведь правильно понимаю, что это интерпретируемый язык ? Тогда возможна ошибка в синтаксисе, и строка с присвоением просто не выполняется. Никакой ошибки не выводится в консоли ?

Попробуй вызвать метод объекта

var obj = new Osm()
//obj.nodes["333"] = "cccc"
obj.insert("333","cccc");


class Osm : ...
{
...
  void insert(QString F,QVariant S)
  {
     m_nodes[F]=S;
  }
...
}
shasoft
Никакой ошибки не выводится. и даже отрабатывает конструкция obj["aaa"] = 1
Т.е. у объекта obj появляется свойство aaa.
Я так понял, что с obj это срабатывает, потому что он наследник от QObject, а QMap нет. Единсвенное, что непонятно, зачем мне доступ к свойству типа QMap в скрипте, если я не могу полноценно с ним работатать. :(

Придется сделать наверное так:

class Osm : ...
{
...
  void nodes(QString key,QVariant value)
  {
     m_nodes[key]=value;
  }
  QVariant nodes(QString key)
  {
     return m_nodes[key];
  }
...
}

Только ещё не разбирался, можно с одним именем две функции сделать. Хотя, там вроде можно функцию с переменным числом параметров делать, так что таки и придется делать.
Алексей1153
написал я то, что под спойлером, а потом задумался, что не пойдёт так ) Хотя, попробуй. Если не прокатит оператор [] , замени его на обычную функцию - пример ниже спойлера

Раскрывающийся текст
можно так сделать

class Osm : ...
{
...
  QVariant& operator[](const QString key/*,QVariant value*/)
  {
     return m_nodes[key];
  }
...
}


obj["333"] = "cccc"


class Osm : ...
{
...
  QVariant& GetValueRef(const QString key)
  {
     return m_nodes[key];
  }
...
}


obj.GetValueRef("333") = "cccc"
shasoft
Свой вариант решения я привел.

Но вот с вашим думаю могут быть проблемы.
Раскрывающийся текст
class Osm : ...
{
...
  QVariant& GetValueRef(const QString key)
  {
     return m_nodes[key];
  }
...
}


obj.GetValueRef("333") = "cccc"
Если элемент с ключом key существует, то всё отлично. А если такого элемент в m_nodes нет?
Алексей1153
мап работает так, что если ключа нет, то он добавится, а значение, связанное с ним, будет дефолтное. Но ссылку на него уже можно вернуть

Если нужно избежать автоматического добавления ключа, следует применять метод find карты
shasoft
Не прокатило
            Q_INVOKABLE QVariant& attr(QString key)
            {
                return m_attrs[key];
            };

вот этот код
var obj = new Osm()
print(obj.attr("aaa"))
obj.attr("aaa") = "11111"
print(obj.attr("aaa"))
выдает
Цитата
undefined

т.е. на присваивании, судя по всему, скрипт завершает работу.
Алексей1153
ждём тогда спецов )
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.