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. [SOLVED] Updating single item in CppModel does not update QML
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] Updating single item in CppModel does not update QML

Scheduled Pinned Locked Moved QML and Qt Quick
9 Posts 2 Posters 10.1k 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.
  • O Offline
    O Offline
    ortogonal
    wrote on last edited by
    #1

    Hi!

    I've made a simple example which have a data model (class derived from QStandardItemModel). I've connected the model from C++ into the QML using setContextProperty(). Every thing works fine as long as I just "display" the model.

    But when I start to update the data in an item it does not update the QML. I've made a simple connection (using Connections element) in QML that connects the models dataChanged signal. I see that signal in the QML when I update the model, but still the Text-element in the ListView delegate will not update.

    This is my code:
    main.cpp
    @#include <QtGui/QGuiApplication>
    #include "qtquick2applicationviewer.h"
    #include "cppmodel.h"
    #include "cppmodelitem.h"

    #include <qqmlengine.h>
    #include <qqmlcontext.h>
    #include <QtQuick/qquickview.h>

    int main(int argc, char *argv[])
    {
    QGuiApplication app(argc, argv);

    CppModel model;
    model.appendRow(new CppModelItem("Item 1"));
    model.appendRow(new CppModelItem("Item 2"));
    model.appendRow(new CppModelItem("Item 3"));
    
    
    QtQuick2ApplicationViewer viewer;
    viewer.rootContext()->setContextProperty("cppModel",  &model);
    viewer.setMainQmlFile&#40;QStringLiteral("qml/datamodeltest/main.qml"&#41;&#41;;
    viewer.showExpanded();
    
    return app.exec&#40;&#41;;
    

    }
    @

    cppmodel.cpp
    @#include "cppmodel.h"
    #include "cppmodelitem.h"

    #include <QDebug>

    CppModel::CppModel()
    {
    CppModelItem dummy("");
    this->setItemRoleNames(dummy.roleNames());
    }

    void CppModel::changeItem(int i)
    {
    if( this->rowCount() > i )
    {
    qDebug() << "using new data for row" << i;

        // This will NOT update the QML-Viewer with the new data.
        // But I can see the dataChanged signal within the QML code.
        this->item(i, 0)->setData("newData", CppModelItem::NameRole);
    
        // Appending row will make the QML-Viewer update
        //this->appendRow(new CppModelItem("Test"));
    }
    

    }
    @

    cppmodelitem.cpp
    @#include "cppmodelitem.h"

    CppModelItem::CppModelItem(const QString& name)
    {
    m_name = name;

    this->setEditable(true);
    

    }

    QHash<int, QByteArray> CppModelItem::roleNames() const
    {
    QHash<int, QByteArray> names;
    names[NameRole] = "name";
    return names;
    }

    QVariant CppModelItem::data(int r) const
    {
    Roles role = (Roles)r;
    switch(role)
    {
    case NameRole:
    return m_name;
    break;
    default:
    return QVariant();
    }
    }
    @

    main.qml
    @import QtQuick 2.0

    Rectangle {
    width: 360
    height: 360

    ListView {
        id: listView
        anchors.fill: parent
    
        delegate: Text {
            height: 18
            width: 360
            text: name
    
            MouseArea {
                anchors.fill: parent
                onClicked: cppModel.changeItem(index)
            }
        }
    
        model: cppModel
    }
    
    Connections {
        target: listView.model
        onDataChanged: {
            console.log("Changing data")
        }
    }
    

    }
    @

    When I run the program I get this debug
    @using new data for row 1
    Changing data
    using new data for row 2
    Changing data@

    To me that says that the C++ function changeItem() is invoked and the connection between C++ and QML is there, but how will I get the Element in the delegate to update?

    Thanks!

    1 Reply Last reply
    0
    • T Offline
      T Offline
      t3685
      wrote on last edited by
      #2

      Have you tried emitting a signal to notify that data has changed?

      1 Reply Last reply
      0
      • O Offline
        O Offline
        ortogonal
        wrote on last edited by
        #3

        I've this Connections
        @
        Connections {
        target: listView.model
        onDataChanged: {
        console.log("Changing data")
        }
        }
        @

        And I can see the log "Changing data". And as far as I understand QStandardItemModel will do the emitting of signals by it self, right?

        1 Reply Last reply
        0
        • T Offline
          T Offline
          t3685
          wrote on last edited by
          #4

          I believe you still have to emit the signal yourself. Here is a thread with a similar problem:

          http://qt-project.org/forums/viewthread/24294

          The "Changing data" you see could have come from a different function that changes the data and not neccessarily from your changeItem function.
          (I could always be wrong of course :))

          1 Reply Last reply
          0
          • O Offline
            O Offline
            ortogonal
            wrote on last edited by
            #5

            Nothing :-(

            I've added the following line to my changeItem() function right after the setData() call.

            @
            emit this->dataChanged(createIndex(i,0), createIndex(i,0));
            @

            The only difference is that I now see to "Chaning data" logs that probably comes from the added the extra emit.

            1 Reply Last reply
            0
            • T Offline
              T Offline
              t3685
              wrote on last edited by
              #6

              Have you had a look at this link?

              I believe it does something similar to what you're trying to do:

              http://www.developer.nokia.com/Community/Wiki/Using_QStandardItemModel_in_QML

              1 Reply Last reply
              0
              • O Offline
                O Offline
                ortogonal
                wrote on last edited by
                #7

                Sorry, but I can't see why that link would help.

                1 Reply Last reply
                0
                • T Offline
                  T Offline
                  t3685
                  wrote on last edited by
                  #8

                  I was thinking you could try out the model they provided to see if it would work with your QML file. Guess I should have been more clearer :)

                  1 Reply Last reply
                  0
                  • O Offline
                    O Offline
                    ortogonal
                    wrote on last edited by
                    #9

                    I solved it!
                    To make it work I implemented my own setData() in CppModelItem, which seems really straight-forward when you think of it!

                    @
                    void CppModelItem::setData(const QVariant &value, int role)
                    {
                    if( role == NameRole )
                    {
                    m_name = value.toString();

                        this->model()->dataChanged(this->index(), this->index());
                    }
                    

                    }
                    @

                    In the setData() I call the models dataChanged() with this index and everything works!

                    1 Reply Last reply
                    0

                    • Login

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