Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Passing QLists to QML
Forum Updated to NodeBB v4.3 + New Features

Passing QLists to QML

Scheduled Pinned Locked Moved QML and Qt Quick
16 Posts 4 Posters 7.3k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Schneidi
    wrote on 12 Feb 2014, 09:01 last edited by
    #7

    Hey onek24,

    thanks for this nice example it looks pretty much like my model.

    In the example above I showed you how I try to pass a list to qml containing a subset of the model.

    This is my data() function.
    @
    QVariant ClipModel::data(const QModelIndex &index, int role) const {
    if (!index.isValid())
    return QVariant();
    if (index.row() >= m_clips.size() || index.row() < 0)
    return QVariant();

    if (role == ObjectRole)
        return QVariant::fromValue(this->m_clips.at(index.row()));
    else if (role == Fklz)
        return QVariant::fromValue(this->m_clips.at(index.row())->getFklz());
    else
        return QVariant::fromValue(this->m_clips.at(index.row()));
    

    }
    @

    This creates a QVariantList for qml.
    Here I load QVariants with the ObjectRole of my model.
    @QList<QVariant> ViewInterface::getClipByFklz(QString fklz)
    {
    QList<QVariant> list;
    QModelIndexList Items =this->model->match(
    this->model->index(0, 0),
    ClipModel::Fklz,
    QVariant::fromValue(fklz),
    -1,
    Qt::MatchRecursive);

    for( int i=0; i<Items.count(); ++i )
    {
        list.append(this->model->data(Items[i],ClipModel::ObjectRole));
    }
    return list;
    

    }@

    My ClipModel stores ClipElements objects.

    On the QML side I try the following.
    model: viewinterface.getClipByFklz(curr_nav_fklz)
    The models of the listviews are set via the ViewInterface::getClipByFklz() function.
    @
    ListView {
    id: grid_clip_list
    anchors.fill: parent
    interactive: false
    orientation: ListView.Horizontal
    clip:true
    model: viewinterface.getClipByFklz(curr_nav_fklz) //each listview gets a model based on the current "fklz" key
    delegate: clip_delegate
    Component.onCompleted: {
    var temp = viewinterface.getClipByFklz(curr_nav_fklz);
    for (var i = 0; i < temp.length; i++)
    {
    console.log(temp[i].fklz); //This prints the fklz property of each ClipElement in the list.
    }
    }
    }
    @

    For debug purposes I load each list a second time in a temporary JS variable to print them.
    The console.log(temp[i].fklz); prints the property perfectly as expected.

    But in the clip_delegate I get an "ReferenceError: fklz is not defined" error.
    @
    Text {
    anchors.fill: parent
    text: {
    console.log(fklz);
    "fklz = " + fklz
    }
    }
    @

    Why can't I access the properties of the ClipElement objects in the delegate ?
    How can I debug the current ListElement of a delegate ?

    1 Reply Last reply
    0
    • S Offline
      S Offline
      Schneidi
      wrote on 12 Feb 2014, 12:26 last edited by
      #8

      Whats the point of getting Lists into QML ? Why is the support of model handling so neglected ?

      Why is there no way to just pass a simple QList<CustomObject*> to qml ?
      I found nothing like that.

      This article explains basically what I need but I didn't understand how this has to be implemented.
      http://lemirep.wordpress.com/2013/04/06/a-practical-case-exposing-qt-c-models-to-qml/

      Any ideas guy ?

      1 Reply Last reply
      0
      • S Offline
        S Offline
        Schneidi
        wrote on 12 Feb 2014, 12:53 last edited by
        #9

        As a workaround for the Problem that i couldn't access the properties of
        the model item. I'm referring to them via model.modelData.

        This seem to work for now.
        @
        Text {
        anchors.fill: parent
        text: {
        console.log(model.modelData.fklz);
        "fklz = " + model.modelData.fklz
        }
        }
        @

        1 Reply Last reply
        0
        • H Offline
          H Offline
          hardcodes.de
          wrote on 12 Feb 2014, 15:53 last edited by
          #10

          [quote author="Schneidi" date="1392207961"]Whats the point of getting Lists into QML ? Why is the support of model handling so neglected ?
          Why is there no way to just pass a simple QList<CustomObject*> to qml ?
          I found nothing like that.
          [/quote]

          That's an answer that I am also waiting for. Everything besides simple data types is like royal PITA or at least full of boilerplate code.

          while(!sleep){++sheep;}

          1 Reply Last reply
          0
          • O Offline
            O Offline
            onek24
            wrote on 13 Feb 2014, 09:25 last edited by
            #11

            Sorry that i couldn't answer. It looks like it is working now? Glad to hear.
            What i would've tried is to create a QList<myModel> and append my models to it. Each model with it's own values. Then you can pass the QList to QML as a model. Theoretically this should work.

            1 Reply Last reply
            0
            • H Offline
              H Offline
              hardcodes.de
              wrote on 14 Feb 2014, 10:19 last edited by
              #12

              The problem is here that you need to derive myModel from QObject and thus must use QList<myModel*> and not QList<myModel>.

              while(!sleep){++sheep;}

              1 Reply Last reply
              0
              • S Offline
                S Offline
                Schneidi
                wrote on 14 Feb 2014, 11:03 last edited by
                #13

                I found a way that works for me.
                As shown above I request submodels as QList<QVariant>.
                This allows me to pass lists of custom objects to qml.

                If I try to pass them as QList<myModel> I would need to register the type to
                qml or not ? QML tells me that the typ QList<myModel> is unkown.

                1 Reply Last reply
                0
                • H Offline
                  H Offline
                  hardcodes.de
                  wrote on 14 Feb 2014, 11:14 last edited by
                  #14

                  [quote author="Schneidi" date="1392375824"]I found a way that works for
                  If I try to pass them as QList<myModel> I would need to register the type to
                  qml or not ? QML tells me that the typ QList<myModel> is unkown.
                  [/quote]

                  IMHO, yes.

                  The funny thing is that Qt has solved that for QList<QObject*>.

                  while(!sleep){++sheep;}

                  1 Reply Last reply
                  0
                  • O Offline
                    O Offline
                    onek24
                    wrote on 14 Feb 2014, 11:39 last edited by
                    #15

                    [quote author="hardcodes.de" date="1392373170"]The problem is here that you need to derive myModel from QObject and thus must use QList<myModel*> and not QList<myModel>.[/quote]
                    [quote author="Schneidi" date="1392375824"]I found a way that works for me.
                    As shown above I request submodels as QList<QVariant>.
                    This allows me to pass lists of custom objects to qml.

                    If I try to pass them as QList<myModel> I would need to register the type to
                    qml or not ? QML tells me that the typ QList<myModel> is unkown.

                    [/quote]

                    Yes, sorry, my bad. Like hardcodes.de already said: You'll have to derive your model from QObject and create the List like QList<QObject*> and append your models to it.

                    1 Reply Last reply
                    0
                    • H Offline
                      H Offline
                      hardcodes.de
                      wrote on 14 Feb 2014, 18:27 last edited by
                      #16

                      So far I see only two ways to handle this:

                      1. you can use something like

                      @
                      Q_PROPERTY(QQmlListPropertyYourNameSpace::YourCustomType nameOfList READ nameOfList)
                      @

                      instead of a Q_PROPERTY with a QList. Therefore you need to register your custom type with

                      @
                      qmlRegisterTypeYourNameSpace::YourCustomType("Name_you_reference_in_QML", majorversionnumber, minorversionnumber, "QMLNameWhateverNeededFor");
                      @

                      And you have to register the class holding the list with setContextProperty. This QQmlListProperty introduces an extra way for the QML side to access the data in your model. But that doesn't work just out the box (again), you have to write extra functions to get/set the data from/into the list (yes, you keep the QList and must add extra functions, e.g. see QQmlListProperty::AppendFunction.
                      What have we got here? A model has been changed (or maybe even polluted if you want), we added all that Q_PROPERTY stuff and the extra functions. IMHO that is ugly.

                      You see the C++ and QML worlds as what they are: 2 different worlds with totally different approaches, object models and data types that need a translator for every communication between the two worlds. They are aliens.
                      From this point of view an adapter pattern would come in handy and I think that's the way to look at all the variations of AbstractItem... models. Those are somehow like the guys with the white flag that transport messages between two parties at war. But this comes at the price that you have to write a lot of bolier plate code to fulfill the protocol both parties have agreed about: the interface functions. IMHO ugly, again. But the model can stay untouched, at least this feels better for me!

                      Either way: more work, both not perfect.
                      Strange when you think about where Qt came from: it originated as C++ framework that enabled you to write UIs with C++ (and yes, there were also AbstractItem... models). My problem is not so much that the UI has to written in QML, that's totally fine. I totally understand why they did it: each new platform and each change in an already supported platform introduced a huge amount of work. This work was transferred to the developer that uses the framework. This developer has to adapt the look and feel of the platform (if there is no library available that does that for you), but from a good starting position and with quite good tools.
                      The point I can't understand is, that they somehow "forgot" an easy and universal way (in the sense of just a few lines of code or even better: no code at all) to get data in and out.
                      Some say it's for your own good: a clean separation of ui and logic. To me it's like someone is saying "we found out that we gave you a hammer and you treated every problem as a nail". And then "our solution is: you keep the nails, we take away the hammer and give you a screwdriver instead". Ah, BTW: you can write Javascript inside QML, so much for separation of UI and logic.

                      So now I took this thread as far off topic as possible and yes it's opinionated:-)

                      while(!sleep){++sheep;}

                      1 Reply Last reply
                      0

                      16/16

                      14 Feb 2014, 18:27

                      • Login

                      • Login or register to search.
                      16 out of 16
                      • First post
                        16/16
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved