[Solved] How to update an element of DataModel from QML and request an update of the ListView?



  • Hello,

    I have an C++ based application which exports a data model to the DeclarativeContext. Displaying the data works fine what I miss is how to update single members of the dataModel from QML and request an update of the ListView which dipslays the data. Can anybody tell me what the correct way to do this.

    What I already tried is to provide some public slots on the dataModel and use the slots to update update the underlying list inside my DataModel and force an refresh but it works very slowly and seems not to be the correct way

    QML
    @
    myModel.setColor(selectedIdInput.text, selectedColorInput.text);
    myModel.refresh();
    @

    C++
    @
    void MyModel::refresh()
    {
    beginResetModel();

    endResetModel();
    

    }

    void MyModel::setColor(int index, QVariant id)
    {
    _pMyDataList->at(index)->setColor(id.toString());
    }
    @

    Can anybody tell me a better way?

    I'm using QtQuick 1.1 with Qt 4.8.4.

    Thanks Michael



  • The built in Qt models all have a dataChanged signal already. So you really shouldn't have to update manually from the QML side. Anytime data is changed in the model, just emit the dataChanged signal.



  • To be a bit more clear, just emit the dataChanged signal in the setColor function. The view should automatically update the changed elements based on what indices you emitted as being changed.



  • About the
    @
    void QAbstractItemModel::dataChanged ( const QModelIndex & topLeft, const QModelIndex & bottomRight )@

    signal I read already but from where I get the QModelIndex parameters or how I have to initialize them?



  • You can get a QModelIndex for your current item with the index function:

    @QModelIndex QAbstractItemModel::index(int row, int column, const QModelIndex & parent = QModelIndex()) const@

    If you really are using a QAbstractItemModel rather than something like QAbstractListModel you'll have to implement this function yourself since it is pure virtual. It should be pretty easy if you're dealing with a simple list model, the model row will correspond directly with the index in your setColor function.



  • thanks for the hints now it works. Here is my solution. In my setter method I create an QModelIndex. With this I call my overwritten setData method. In the setData method I update the data and send the dataChanged() signal. The setter method is called from QML with the index of the ListView element I want to changed.

    C++:

    @bool MyColorModel::setData(const QModelIndex &index, const QVariant &value, int role)
    {
    MyColor* myColor = _pMyColorList->at(index.row());

    if (role == IdRole)
        myColor->setId(value.toString());
    else if (role == ColorRole)
        myColor->setColor(value.toString());
    
    emit dataChanged(index, index);
    
    return TRUE;
    

    }@

    @void MyColorModel::setColor(int index, QVariant color)
    {
    QModelIndex modelIndex = this->index(index);
    setData(modelIndex, color, ColorRole);
    return;
    }@

    QML:
    @colorModel.setColor(selectedIndex, colorpicker.colorValue);@


Log in to reply
 

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