Model支持插入和删除行,需要自己添加插入和删除的函数,并且在插入函数中(插入数据前)调用
void QAbstractItemModel::beginInsertRows(const QModelIndex &parent, int first, int last)
插入数据完成后,调用
void QAbstractItemModel::endInsertRows();
类似地,在删除开始前调用:
void QAbstractItemModel::beginRemoveRows(const QModelIndex &parent, int first, int last)
删除完成后调用:
endRemoveRows();
在stringlistmodel.h文件中:
#ifndef STRINGLISTMODEL_H
#define STRINGLISTMODEL_H
#include <QAbstractListModel>
#include <QStringList>
class MyStringListModel : public QAbstractListModel
{
Q_OBJECT
public:
enum {
DescriptionRole = Qt::UserRole,
};
explicit MyStringListModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role) const override;
virtual QHash<int, QByteArray> roleNames() const override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
bool insertRows(int position, int rows, const QModelIndex &parent = QModelIndex()) override;
bool removeRows(int position, int rows, const QModelIndex &parent = QModelIndex()) override;
//为了演示添加的测试接口
Q_INVOKABLE bool testInsertRows(int position, int rows);
Q_INVOKABLE bool testRemoveRows(int position, int rows);
private:
QStringList stringList;
};
#endif // STRINGLISTMODEL_H
在stringlistmodel.cpp中:
#include "stringlistmodel.h"
MyStringListModel::MyStringListModel(QObject *parent)
{
Q_UNUSED(parent);
stringList.append("111111");
stringList.append("222222");
}
int MyStringListModel::rowCount(const QModelIndex &) const
{
return stringList.count();
}
QVariant MyStringListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (index.row() >= stringList.size())
return QVariant();
if (role == DescriptionRole)
return stringList.at(index.row());
else
return QVariant();
}
Qt::ItemFlags MyStringListModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return Qt::ItemIsEnabled;
return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
}
bool MyStringListModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (index.isValid() && role == DescriptionRole)
{
stringList.replace(index.row(), value.toString());
emit dataChanged(index, index);
return true;
}
return false;
}
QHash<int, QByteArray> MyStringListModel::roleNames() const
{
QHash<int, QByteArray> names;
names[DescriptionRole] = "description";
return names;
}
bool MyStringListModel::insertRows(int position, int rows, const QModelIndex &parent)
{
if (position < 0 || position > stringList.size() || rows <= 0)
return false;
beginInsertRows(parent, position, position+rows-1);
for (int row = 0; row < rows; ++row)
{
stringList.insert(position, "aaa"); //这里以为了演示,添加的是aaa,实际可以添加""
}
endInsertRows();
return true;
}
bool MyStringListModel::removeRows(int position, int rows, const QModelIndex &parent)
{
if ( !(position >= 0 && position <= stringList.size()-1) || rows <= 0)
return false;
beginRemoveRows(parent, position, position+rows-1);
for (int row = 0; row < rows; ++row)
{
stringList.removeAt(position);
}
endRemoveRows();
return true;
}
bool MyStringListModel::testInsertRows(int position, int rows)
{
return insertRows(position, rows);
}
bool MyStringListModel::testRemoveRows(int position, int rows)
{
return removeRows(position, rows);
}
在man.cpp中:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "stringlistmodel.h"
#include <QtQml>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
qmlRegisterType<MyStringListModel>("RegStringListModel", 1, 0, "MyStringListModel");
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
main.qml文件中:
import QtQuick 2.9
import QtQuick.Window 2.2
import RegStringListModel 1.0
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.0
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
ColumnLayout {
Frame {
ListView {
id: listViewId
implicitWidth: 250
implicitHeight: 250
clip: true
model: MyStringListModel {}
delegate: RowLayout {
width: parent.width
TextField {
text: model.description
onEditingFinished:
{
model.description = text;
console.log("model.description is: ", model.description);
}
Layout.fillWidth : true
}
}
}
} //end Frame
RowLayout {
Button {
text: qsTr("Add new item")
onClicked: listViewId.model.testInsertRows(listViewId.count, 1);
Layout.fillWidth: true
}
Button {
text: qsTr("Remove completed")
onClicked: listViewId.model.testRemoveRows(listViewId.count-1, 1);
Layout.fillWidth: true
}
}
}
}
运行效果: