Binding C++ Class to QML to create dynamic ListViews, NoGo :-(



  • ----updated dynamic part to at least compile, updated code and download -----
    Hello !
    (Using Qt 5.3)
    I tried to create a compact sample, but its still too big to post all the files here separately.

    Here is a link to "bindtest.zip" via uploaded.com, beware of spam/ugly pix:

    http://ul.to/lqemy5jx

    Okay, i will try to post the essence of the files here anyways (6000 char limit)

    I tried to create a simple Class in C++ containing a StringList and an index.
    I Instantiated two Objects of this Class and exposed them via "setContextProperty"

    This should be used in QML to initialize a ListView and to be in sync with it.
    So whenever a User changes the index in QML, C++ should be notified AND vice versa.

    So when i create two Component qml files using the hardwired names set in "setContextProperty" it seems to work fine.

    But for the life of me i cannot create a single component file and pass the DataObject to it as a parameter, i simply do not know how to do it, although i tried.

    My "final" target ist to create a QML Object dynamically and pass the DataObject to it, this does not work either :-(

    So here it comes, code snippets of my sample Project:

    Declaring my oh-so-simple Class (DataObject.h)
    @
    ...
    Q_PROPERTY( int index MEMBER m_index NOTIFY indexChanged )
    public slots:
    int count() const { return m_Elements.count(); }
    QString at(int idx) const { return m_Elements.at(idx); }
    public:
    void setIndex(int theInt) { m_index = theInt; }
    signals:
    void indexChanged(int);
    public: // too lazy to write accessors for this sample, so make it public
    QStringList m_Elements;
    private:
    int m_index;
    ...
    @
    Registering it in main.cpp:
    @
    qmlRegisterType<DataObject>("bindtestTypes", 1, 0, "DataObject");
    @

    Here is the part of "dialog.cpp" that initializes and exposes two DataObects:
    @
    //preparing first list
    m_firstDO.m_Elements = QStringList() << "A" << "B" << "C" << "D";
    m_firstDO.setIndex(0);

    ...
    //publish the 2 Dataobjects
    m_engine.rootContext()->setContextProperty( "cppDataList_1", &m_firstDO);
    m_engine.rootContext()->setContextProperty( "cppDataList_2", &m_secondDO);
    @

    Here is the QML file "ShowLists.qml" that should simply show the 2 ListVies on Top of each other, i commented the 2 NOT working approaches that i would love to work, especially the dynamic one:
    @
    import QtQuick 2.2
    import QtQuick.Window 2.1
    import bindtestTypes 1.0

    Window {
        visible: true
        width: 200
        height: 400
        Rectangle{
            anchors.fill: parent
    //dynamic: does not work :-(
    //needs click to be activated
    //        Rectangle{
    //            id:upperList
    //            anchors.top: parent.top;
    //            anchors.left: parent.left
    //            width:200
    //            height:200
    //            MouseArea{
    //                anchors.fill: parent
    //                onClicked: {
    //                    var component = Qt.createComponent("SimpleList.qml");
    //                    var dyncbb = component.createObject(parent, {"theDO": cppDataList_1});
    //                }
    //            }
    
    //        }
    //        Rectangle{
    //            id:lowerList
    //            anchors.bottom: parent.bottom;
    //            anchors.left: parent.left
    //            width:200
    //            height:200
    //            MouseArea{
    //                anchors.fill: parent
    //                onClicked: {
    //                    var component = Qt.createComponent("SimpleList.qml");
    //                    var dyncbb = component.createObject(parent, {"theDO": cppDataList_2});
    //                }
    //            }
    //        }
    
    
    //static: would not be my first choice but isnt working anyways...
    //        SimpleList {
    //            id:upperList
    //            property DataObject theDO: cppDataList_1
    //            anchors.top: parent.top;
    //            anchors.left: parent.left
    //        }
    //        SimpleList {
    //            id:lowerList
    //            property DataObject theDO: cppDataList_2
    //            anchors.bottom: parent.bottom;
    //            anchors.left: parent.left
    //        }
    
    //hardwired works, but its not workable for my rather complex project...
            SimpleList1 {
                id:upperList
                anchors.top: parent.top;
                anchors.left: parent.left
            }
            SimpleList2 {
                id:lowerList
                anchors.bottom: parent.bottom;
                anchors.left: parent.left
            }
        }
    }
    

    @

    So, can anyone of you help me to get this solved ??

    Greetings & thanks for any help !

    Nils



  • Ooops:

    IF you dare to follow the uploaded link and run my sample you can see one more glitch. It displays 2 Windows, one QQQuickWIndow and a Widget. In the Widget i can change the indexes as well as in the QML Window. At first they are in sync but then the QML Window does not get updated anymore by changing the index in the widget, i hope its a glitch and not another general error i made.

    Nils



  • Argh, i found the problem, i did a very simple mistake:

    The property i want to set in the SimpleList Component has to be in the root Object, so instead of this:
    @
    Rectangle {
    ListView {
    id: list_view
    property DataObject theDO
    ...
    @
    It has to be done this way:
    @
    Rectangle {
    property DataObject theDO
    ListView {
    id: list_view
    ...
    @
    Wow, thats an easy solution for a (seemingly) complex Problem.

    Greetings,

    Nils


Log in to reply
 

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