QAbstractListModel insertRows not working properly

时间秒杀一切 提交于 2019-12-07 09:17:51

问题


I have a subclass of QAbstractListModel and attached this model subclass with GridView. When I remove rows from my subclass, the GridView gets updated but when I insert rows in the model the GridView does not gets updated. I have implemented the removeR

I have a very simple subclass of QAbstractListModel and I have attached with it a QML GridView. I have two buttons Add/Remove on the GUI. Pressing Add adds a string to the model and gui updated and pressing remove removes last string from the model and gui updates. My problem is when I add only one row is inserted and when I remove nothing happens on the GUI. Given is the implementation of my model subclass and QML file.

namesmodel.cpp

NamesModel::NamesModel(QObject *parent) :
    QAbstractListModel(parent)
{
    QHash<int, QByteArray> roles;
    roles[Qt::UserRole + 1]  = "name";
    setRoleNames(roles);
}
int NamesModel::rowCount(const QModelIndex &parent) const
{
    return this->namesList.count();
}
QVariant NamesModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    switch(role) {
    case (Qt::UserRole + 1):
        return this->namesList.at(index.row());
    default:
        return QVariant();
    }
    return QVariant();
}
bool NamesModel::insertRow(int row, const QModelIndex &parent)
{
    if ( parent.isValid() )
        return false;
    qDebug() << "Row = " << row;
    beginInsertRows(parent, row, row);
    this->namesList.insert(row, ("Hello World " + QString("%1").arg(row)));
    endInsertRows();
    return true;
}
bool NamesModel::insertRows(int row, int count, const QModelIndex &parent)
{
    int existing_count = this->namesList.count();
    beginInsertRows(parent, row, count);
    for ( int i = existing_count; i < (existing_count + count); i++ )
        this->namesList.insert(i, QString("Multi Hello World = %1").arg(i));
    endInsertRows();
    return true;
}
bool NamesModel::removeRows(int row, int count, const QModelIndex &parent)
{
    int existing_count = this->namesList.count();
    beginRemoveRows(parent, row, count);
    for ( int i = (existing_count + count); i < existing_count; i-- )
        this->namesList.removeAt(i);
    endRemoveRows();
    return true;
}

bool NamesModel::removeRow(int row, const QModelIndex &parent)
{
     beginRemoveRows(parent, row, row);
     this->namesList.removeAt(row);
     endRemoveRows();
}

void NamesModel::addName()
{
    int index = this->namesList.count();
    //insertRow(index, QModelIndex());
    insertRows(index, 5, QModelIndex());
    emit layoutChanged();
    emit dataChanged(this->index(index), this->index(this->namesList.count()));
}
void NamesModel::removeName()
{
    int index = this->namesList.count();
    //removeRow(index, QModelIndex()/*this->index(this->namesList.count())*/);
    removeRows(index, 5, QModelIndex());
    emit layoutChanged();
    emit dataChanged(this->index(index), this->index(index + 5));
}

main.qml

Rectangle {
    width: 360
    height: 360
    Text {
        height: 20
        width: 360/2;
        text: "Add Name"
        MouseArea {
            anchors.fill: parent
            onClicked: {
                names.addName();
                console.log("Add Name");
            }
        }
    }
    Text {
        height: 20;
        width: 360/2;
        x: 360/2
        text: "Remove Name";
        MouseArea {
            anchors.fill: parent
            onClicked: {
                names.removeName();
                console.log("Remove Name");
            }
        }
    }

    Component {
        id: gridDelegate

        Text {
            width: 19;      // These are the dimensions of icon image.
            height: 16
            font.pixelSize: 12
            text: name;
        }
    }
    GridView {
        y: 21
        boundsBehavior: Flickable.StopAtBounds

        focus: true
        model: names;
        delegate: gridDelegate
    }
}

I am calling beginInsertRows / endInsertRows and beginRemoveRows / endRemoveRows but it does not seems to work. As suggested on other similar threads I have also called layoutChanged / dataChanged after begin / end InserRows but no effect.

Actually I have almost the same problem with my actual project. I have created this application to test whats wrong with this beginInsertRows etc.

Any help is appreciated.

Regards Farrukh Arshad.


回答1:


The way you are calling beginInsertRows is incorrect. In the documentation for the function, you need to provide the first index of the new item (row) and the last "new" index of the items being inserted (row + count - 1).

bool NamesModel::insertRows(int row, int count, const QModelIndex &parent)
{
    int existing_count = this->namesList.count();
    beginInsertRows(parent, row, row + count - 1);
    for ( int i = row; i < (row + count - 1); i++ )
        this->namesList.insert(i, QString("Multi Hello World = %1").arg(i));
    endInsertRows();
    return true;
}

The same goes for beginRemoveRows.

bool NamesModel::removeRows(int row, int count, const QModelIndex &parent)
{
    int existing_count = this->namesList.count();
    beginRemoveRows(parent, row, row + count - 1);
    for ( int i = (row + count - 1); i <= row; i-- )
        this->namesList.removeAt(i);
    endRemoveRows();
    return true;
}


来源:https://stackoverflow.com/questions/12394751/qabstractlistmodel-insertrows-not-working-properly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!