Exposing QList<T>to QML : registering QQmlListProperty in QML type system using qmlRegisterType method



  • I'm trying to access a QList<MyOject> from QML so I'm using QQmlListProperty

    here is a part of the code :

    the class MyObject code : MyObject.h

    @

    #ifndef MYOBJECT_H
    #define MYOBJECT_H

    #include "track.h"
    #include <QObject>
    #include <QtQml/qqml.h>

    class MyObject : public QObject{

    Q_OBJECT
    Q_PROPERTY(QQmlListProperty<Track> tracks READ tracks)

    public:
    explicit MyObject(QObject *parent = 0);
    QQmlListProperty<Track> tracks();

    private:
    QList<Track*> Tracks;
    static void append_track(QQmlListProperty<Track> *list, Track *track);

    --
    

    };@

    the class MyObject : MyObject.cpp

    @
    QQmlListProperty <Track> MyObject::tracks()
    {
    return QQmlListProperty<Track>(this, 0,&MyObject::append_track,
    QQmlListProperty<Track>::CountFunction(),
    QQmlListProperty<Track>::AtFunction(),
    QQmlListProperty<Track>::ClearFunction());
    }
    void MyObject::append_track(QQmlListProperty<Track> list, Track track)
    {
    MyObject
    obj = qobject_cast<MyObject
    >(list->object);
    obj->Tracks.append(track);
    }
    @

    and in the main.cpp

    @
    #include <QApplication>
    #include <QDeclarativeView>
    #include <QDeclarativeContext>
    #include <QtQml/QQmlEngine>
    #include "MyObject.h"
    #include "track.h"

    Q_DECL_EXPORT int main(int argc, char *argv[])
    {

    QScopedPointer<QApplication> app(createApplication(argc, argv));
    
    MyObject *myobj  = foo();   //initialisation of the main object
    
    qmlRegisterType<Track>("type.base",1,0,"track");
    Track track;
    QDeclarativeView view;
    QDeclarativeContext *context = view.rootContext();
    context->setContextProperty("MyObject",myobj);
    context->setContextProperty("track",&track);
    view.setSource(QUrl::fromLocalFile&#40;"qml/Myproject/main.qml"&#41;&#41;;
    view.show(&#41;;
    
    return app->exec&#40;&#41;;
    

    }
    @

    So when compiling i have 4 error :

    • In function QQmlPrivate::QQmlElement<Track>::~QQmlElement(&#41;': error : undefined reference toQQmlPrivate::qdeclarativeelement_destructor(QObject*)'
    • In function QQmlPrivate::QQmlElement<Track>::~QQmlElement()': error : undefined reference toQQmlPrivate::qdeclarativeelement_destructor(QObject*)'
    • In function int qmlRegisterType<Track>(char const*, int, int, char const*)': undefined reference toQQmlPrivate::qmlregister(QQmlPrivate::RegistrationType, void*)'
    • ld returned 1 exit status

    Note : just before facing this problem I had some issues :

    • I'm not using QmlApplicationViewer and I use QDeclarativeView and QDeclarativeContext instead because I couldn't access the setContextProperty() method from a QDeclarativeView viewer. So if you have a trick for this please share :).
    • in the QQmlListProperty <Track> MyObject::tracks() method i couldn't just return :
      @
      return QQmlListProperty<Track>(this, 0,&MyObject::append_track);
      @

    because i had this error :
    @
    In member function 'QQmlListProperty<Track> MyObject::tracks()':error : no matching function for call to 'QQmlListProperty<Track>::QQmlListProperty(MyObject* const, int, void () (QQmlListProperty<Track>, track*))'
    candidates are : ...
    @

    so I added :

    @
    return QQmlListProperty<Track>(this, 0,&MyObject::append_track,
    QQmlListProperty<Track>::CountFunction(),
    QQmlListProperty<Track>::AtFunction(),
    QQmlListProperty<Track>::ClearFunction());
    @

    but I don't know if what I did is a convenient way to fix this problem?

    • basically what I want to do is to access a string element from the list tracks from QML by doing something like :

    @
    import QtQuick 1.1

    Rectangle {
    width: 360
    height: 360
    Text {

        text: qsTr(MyObject.tracks.at(..))
        anchors.centerIn: parent
    }
    
    MouseArea {
        anchors.fill: parent
        onClicked: {
            Qt.quit();
        }
    }
    

    }
    @

    thank you in advance :)



  • Did you ever find a solution to this? I'm having the exact same issue and can't find where the problem is.



  • Not yet ! Please let me know if you find a solution



  • QQmlPrivate et al are from QtQuick 2. Elsewhere, you #include <QDeclarativeWhatever> stuff, which is QtQuick 1. Your link / build options are wrong, I assume.

    QQmlListProperty works fine with QtQuick 2, and QDeclarativeListProperty works fine with QtQuick1 - but don't mix QtQuick1 and QtQuick2, that won't work.

    If you want an example of using QQmlListProperty / QDeclarativeListProperty you can see, for example: https://github.com/nemomobile/nemo-qml-plugin-social/blob/master/src/facebook/facebookphotointerface.h

    Cheers,
    Chris.



  • I found the solution to my problem. Instead of including QQmlEngine I included QtQml and everything works perfectly now.
    @chrisadams my entire project is QtQuick2 based and had no QtQuick1



  • Hi.

    In your code snippet above in main.cpp, you have (and I quote):

    @
    #include <QApplication>
    #include <QDeclarativeView>
    #include <QDeclarativeContext>
    @

    You should use instead:

    @
    #include <QGuiApplication>
    #include <QQuickView>
    #include <QQmlContext>
    @

    because the QDeclarative* includes are for QtQuick1 rather than QtQuick2.

    Cheers,
    Chris.



  • That is not my code. The only code on this post belongs to oObasselOo. And yes he is definitely using QtQuick1 I am not.

    I was just trying to tell you the the problems isn't necessarily QtQuick1 because I was experiencing the same thing in QtQuick2.



  • Oh! Sorry, I clearly wasn't paying attention. My bad. You get the same error? If you #include <qqml.h> does it fix the issue? I expect not, since I assume that the QQmlEngine header would include that, but clearly there's some header in the module which is included by the module include (QtQml) but not from QQmlEngine or QQmlView... Strange.

    Cheers,
    Chris.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.