Results 1 to 2 of 2

Thread: QtScript bindings to advanced containers (QMap, QList, etc)

  1. #1
    Join Date
    Mar 2008
    Posts
    11
    Thanks
    1
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Lightbulb QtScript bindings to advanced containers (QMap, QList, etc)

    In my current project I'm returning XML/RPC data converted to QMap on the C++ side and I'd like to expose these to QtScript for automated testing and this has proven to be quite the hassle (these aren't generated by the binding generator).

    My two main hopes are for something to wrap QMap<QString,QString> and QMap<QString, QMap<QString, QString> >

    My open question is this easily possible via some trick I am completely unaware of or is this as complicated as it seems.

    So far my approaches have been:

    1 ) Create a class which inherits from QObject and QMap<QString,QString> with method redirection:
    Qt Code:
    1. class NewMap : public QObject, public QMap<QString, QString> {
    2. public:
    3. NewMap(QObject *parent=0) : QObject(parent){}
    4. Q_INVOKABLE void insert(const QString& key, const QString& value)
    5. {
    6. QMap<QString,QString>::insert(key,value);
    7. }
    8. };
    9. Q_SCRIPT_DECLARE_QMETAOBJECT(NewMap, QObject*);
    To copy to clipboard, switch view to plain text mode 
    This doesn't compile because QObject* is no-copy

    2) Attempted to use Q_DECLARE_METATYPE and defined mapToScriptValue and ScriptValueToMap functions which use a java object to try and build up a map, however I'm going to have to define ALOT of functions and basically recreate the map logic.
    This approach started to become unwieldy and would take much effort to allow iteration, would also need to define a pair<key,value> type.
    * There is also no way on the C++ side that I can find to return all properties defined on a QScriptValue, this kind of mucks object.TestIndex = TestValue definitions.


    In QtScript i have imported the Qt.Core extension and I'm able to return QStringList from a C++ object (by value) so the binding generator has managed to prototype a class which inherits from QList<QString>. Apparently the Qt Creators are way way more savy than I am at this.

    My ultimate goal is to be able to do this in C++, and the following in QtScript:
    Qt Code:
    1. //C++
    2. class ExposedScriptObject : public QObject {
    3. ...
    4. typedef QMap<QString, QString> StringMap
    5. Q_INVOKABLE StringMap returnMap()
    6. {
    7. StringMap map;
    8. m["TestKey"] = "TestValue";
    9. return m;
    10. }
    11. };
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. //QtScript
    2.  
    3. var exposedScriptObject = new ExposedScriptObject();
    4. var myMap = exposedScriptObject.returnMap();
    5. print ( myMap["TestIndex"] );
    6. //Or also acceptible
    7. print ( myMap.value("TestIndex") );
    8.  
    9. //There would also need to be a means of iteration of
    10. //Key/Value pairs such as
    11. for( KeyValue in myMap)
    12. {
    13. print (KeyValue.key + " : " KeyValue.value + "\n");
    14. }
    To copy to clipboard, switch view to plain text mode 

    I'm all out of ideas and cannot connect the dots in Qt/QtScript to do this.

  2. #2
    Join Date
    Mar 2008
    Posts
    11
    Thanks
    1
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QtScript bindings to advanced containers (QMap, QList, etc)

    I figured out how to get what I wanted, sharing the code for anyone else interested.
    Qt Code:
    1. //header
    2. class ScriptMap : public QMap<QString, QVariant> {
    3. }; // work around because typedefs do not register correctly.
    4. Q_DECLARE_METATYPE(ScriptMap);
    5.  
    6. //source
    7. QScriptValue ScriptMapToScriptValue(QScriptEngine* eng, const ScriptMap& map)
    8. {
    9. ScriptValue a = eng->newObject();
    10. ScriptMap::const_iterator it(map.begin());
    11. for(; it != map.end(); ++it)
    12. {
    13. QString prop = it.key();
    14. prop.replace(' ', '_');
    15. a.setProperty(prop, qScriptValueFromValue(eng, it.value()));
    16. }
    17. return a;
    18. }
    19.  
    20. void ScriptMapFromScriptValue( const QScriptValue& value, ScriptMap& map)
    21. {
    22. QScriptValueIterator itr(value);
    23. while(itr.hasNext())
    24. {
    25. itr.next();
    26. map[itr.name()] = qscriptvalue_cast<ScriptMap::mapped_type>(itr.value());
    27. }
    28. }
    29.  
    30. void registerScriptMetaTypes(QScriptEngine* engine)
    31. {
    32. qScriptRegisterMetaType<ScriptMap>(engine, ScriptMapToScriptValue, ScriptMapFromScriptValue);
    33. }
    To copy to clipboard, switch view to plain text mode 

    This allows me to do
    Qt Code:
    1. var myMap = getMap();
    2. for( key in myMap )
    3. {
    4. print( myMap[key] );
    5. }
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. QtScript Bindings Generator ScriptShell Event Binding
    By JohannesMunk in forum Qt Programming
    Replies: 2
    Last Post: 10th April 2010, 13:10
  2. Replies: 0
    Last Post: 25th June 2009, 08:17
  3. QMap in QList ?
    By npc in forum Newbie
    Replies: 2
    Last Post: 5th February 2007, 11:51

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.