Results 1 to 6 of 6

Thread: Access QScriptEngine from QML executed javascript

  1. #1
    Join Date
    Oct 2007
    Posts
    78
    Thanks
    1
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Access QScriptEngine from QML executed javascript

    If I am using import "myscript.js" as MyScript in a QML file.

    inside of myscript.js referencing an object that has been sub classed as scriptable the engine() variable will be null.

    Anyone know a way to get access to the QScriptEngine used to call the script file from the QML code?

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Thumbs down Re: Access QScriptEngine from QML executed javascript

    QDeclarativeView::engine()
    Note QML is not QtScript, there is no QScriptEngine for it. If you need a QScriptEngine you have to bind it with the declarative context yourself but it will not be related to the engine/context used by QML itself.
    Last edited by wysota; 22nd October 2010 at 19:27.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Oct 2007
    Posts
    78
    Thanks
    1
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Access QScriptEngine from QML executed javascript

    MyScript.js
    Qt Code:
    1. function doSomethingFromScriptFile()
    2. {
    3. for (var i=0; i < grabQObject.maxQObjects; i++)
    4. {
    5. var myQObject = grabQObject.objectAt(i);
    6.  
    7. myQObject.doMore();
    8. }
    9. }
    To copy to clipboard, switch view to plain text mode 
    This code is using a known QObject passed to the QML file by view.rootContext()->setContextProperty("grabQObject",grabQObject); to grab and return a new QObject each time through the loop so the javascript can process it.

    MyQML.qml
    Qt Code:
    1. import Qt 4.7
    2.  
    3. import "MyScript.js" as MyScript
    4.  
    5. Rectangle {
    6. id: container
    7. width: 600; height: 480
    8. color: "lightgray"
    9.  
    10. Button {
    11. text: "RunScript"
    12. onClicked: {
    13. MyScript.doSomethingFromScriptFile();
    14. }
    15. }
    16. }
    To copy to clipboard, switch view to plain text mode 
    QML code with a simple button and mouse click area to run doSomethingFromScriptFile() from MyScript.js

    main.cpp
    Qt Code:
    1. #include <qdeclarative.h>
    2. #include <QDeclarativeView>
    3. #include <qdeclarativecontext.h>
    4.  
    5. int main(int argc, char *argv[])
    6. {
    7. QApplication app(argc, argv);
    8.  
    9. QDeclarativeView view;
    10.  
    11. view.rootContext()->setContextProperty("grabQObject",grabQObject);
    12.  
    13. view.setSource(QUrl::fromLocalFile("MyQML.qml"));
    14. view.show();
    15. }
    To copy to clipboard, switch view to plain text mode 
    This is just enough c++ code to get us to execute the QML file and pass it our QObject grabQObject.


    Now when I was using QtScript before I could just subclass QScriptable and do somethinglike this.

    grabQObject.h
    Qt Code:
    1. class GrabQObject : public QObject, protected QScriptable
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. GrabQObject(QObject *parent = 0);
    7.  
    8. public slots:
    9. QScriptValue objectAt(int index);
    10. int maxQObjects() { return m_count; }
    11.  
    12. private:
    13. QList <QObject *> availableObjects;
    14. int m_count;
    15. }
    To copy to clipboard, switch view to plain text mode 

    grabQObject.cpp
    Qt Code:
    1. QScriptValue grabQObject::objectAt(int index)
    2. {
    3. if (index > availableObjects.size())
    4. return engine()->nullValue();
    5. else
    6. return engine()->newQObject(availableObjects.at(index));
    7. }
    To copy to clipboard, switch view to plain text mode 

    This would use the calling QScriptEngine to make a returnable QObject formated as a QScriptValue and all was good.


    My problem now is being able to access each new QObject as I loop through them in the script. When I call myQObject.doMore(); I get.


    TypeError: Result of expression 'myQObject' [undefined] is not an object.

    Not sure what is going wrong here and still learning QML and how it executes javascript, any help would be greatly appreciated.

    Bob

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Access QScriptEngine from QML executed javascript

    I'm not sure what you need QScriptable here for. If you return a QObject from a custom type, QtScript should wrap it into a QScriptValue on its own so your objectAt() method might look like this:
    Qt Code:
    1. QObject* grabQObject::objectAt(int index) const {
    2. if(index > availableObject.size())
    3. return 0;
    4. return availableObjects.at(index);
    5. }
    To copy to clipboard, switch view to plain text mode 

    Anyway... back to QtQuick...

    In general I think that returning an object like in the method above should be ok too (just don't try to return QScriptValue, it won't work). Of course remember to make the objectAt() method invokable from QML using Q_INVOKABLE or by declaring it as a slot!
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Oct 2007
    Posts
    78
    Thanks
    1
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Access QScriptEngine from QML executed javascript

    Thank you got the quick response.

    I was wrapping QScriptValue that way because it just didn't seem to want to work otherwise. Most likely something else I was doing wrong, that portion of the code is fairly old now.

    I just noticed something in your reply that I missed in the code earlier. When I was returning the value it was not as a generic QObject but rather as the specific type.

    I was using qRegisterMetaType<CustomQObject *>("CustomQObject"); but it was not being recognized in the script.

    It seems I am not clearly defining my types somehow.

    Thanks again for the help

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Access QScriptEngine from QML executed javascript

    Usually you use qRegisterMetaType (or qScriptRegisterMetaType) only for value-based types. Subclasses of QObject already have a meta-type. And if you want a meta-type registered first you have to have it, so to be able to perform qRegisterMetaType<X> you need to do Q_DECLARE_METATYPE(x) first.

    If you want a custom QObject to be convertible to/from QtScript, you'd need to use qScriptRegisterMetaType passing it two functions to convert to and from a QScriptValue. See the docs for details. For QML you might need qmlRegisterType() although I don't have any practical experience with QML so I'm just guessing.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


Similar Threads

  1. QThread slot executed in GUI thread
    By tnyblom in forum Qt Programming
    Replies: 13
    Last Post: 25th May 2010, 08:49
  2. QtWebKit access HTML manipulated by javascript
    By rbp in forum Qt Programming
    Replies: 1
    Last Post: 19th September 2009, 03:29
  3. Replies: 3
    Last Post: 14th October 2008, 22:04
  4. Interpretting javascript using QScriptEngine
    By Saranakumardb in forum Qt Programming
    Replies: 8
    Last Post: 31st July 2008, 19:56
  5. Qt::WA_DeleteOnClose while a child QDialog is executed
    By nooky59 in forum Qt Programming
    Replies: 4
    Last Post: 11th July 2008, 13:45

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.