背景
Qt 模型视图编程中模型定义了标准接口对数据进行访问,可根据需求继承对应的抽象模型类来实现自定义的数据模型。一个基本的数据模型至少要实现以下虚函数:
①.rowCount:行数,返回要显示多少行;
②.columnCount:列数,返回要显示多少列
③.data:读取数据,返回每个单元格要显示的内容
视图不会主动更新数据的显示,模型使用 dataChanged 信号通知视图数据发生变化。
模型增删行列
①.概述
通常在应用程序的数据录入界面中,用户需要能够对当前数据进行插入或者删除;在添加新数据时一般都是先插入空行,再进行数据编辑。
②.关键虚函数
insertRows:数据模型对外提供的插入新行的接口,需要传入要添加的位置及行数;
removeRows:数据模型对外提供的删除指定行的接口,需要传入要删除的位置及行数。
③.重要方法
beginInsertRows:需要在插入新行前调用,会自动触发 rowsAboutToBeInserted 信号;
endInsertRows:需要在插入新行完成后调用,会自动触发 rowsInserted 信号。
beginRemoveRows:需要在删除行之前调用,会自动触发 rowsAboutToBeRemoved 信号;
endRemoveRows:需要在删除行完成之后调用,会自动触发 rowsRemoved 信号。
模型插入新行
①.TableModelDemo.h 文件
#include <QAbstractTableModel>
struct student
{
QString name;
int age;
QString sex;
};//测试用数据结构
Q_DECLARE_METATYPE(student)
class TableModelDemo : public QAbstractTableModel
{
Q_OBJECT
public:
TableModelDemo(QList<student> & list, QObject *parent = nullptr):QAbstractTableModel(parent),m_list(list){};
~TableModelDemo() {};
public:
int rowCount(const QModelIndex &parent) const override;//
int columnCount(const QModelIndex &parent) const override;//
QVariant data(const QModelIndex &index,int role) const override;//
Qt::ItemFlags flags(const QModelIndex &index)const override;//
bool setData(const QModelIndex &index,const QVariant & value, int role = Qt::EditRole) override;//
bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;//插入行
private:
QList<student> &m_list;//对内存中数据的引用
public:
void setCustomData(QList<student> & l);
};
②.TableModelDemo.cpp 文件
bool TableModelDemo::insertRows(int row, int count, const QModelIndex &parent /*= QModelIndex()*/)
{
beginInsertRows(parent,row,row+count-1);
for (int i = row; i < row + count; ++i)
{
m_list.insert(i, student());
}
endInsertRows();
return true;
}
③.数据模型初始化
QList<student> m_list;//全局数据
student s;
s.age = 18;
s.name = "张三";
s.sex = "男";
m_list.append(s);
s.age = 16;
s.name = "李四";
s.sex = "女";
m_list.append(s);
auto mode = new TableModelDemo(m_list);
ui.tableView->setModel(mode);
④.末尾插入行
connect(ui.pushButton, &QPushButton::clicked, [mode]() {
mode->insertRows(m_list.size(), 2);//末尾插入2行
});
模型删除行
①.TableModelDemo.h 文件
class TableModelDemo : public QAbstractTableModel
{
Q_OBJECT
public:
TableModelDemo(QList<student> & list, QObject *parent = nullptr):QAbstractTableModel(parent),m_list(list){};
~TableModelDemo() {};
public:
int rowCount(const QModelIndex &parent) const override;//
int columnCount(const QModelIndex &parent) const override;//
QVariant data(const QModelIndex &index,int role) const override;//
Qt::ItemFlags flags(const QModelIndex &index)const override;//
bool setData(const QModelIndex &index,const QVariant & value, int role = Qt::EditRole) override;//
bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;//插入行
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override;//删除行
private:
QList<student> &m_list;//对内存中数据的引用
public:
void setCustomData(QList<student> & l);
};
②.TableModelDemo.cpp 文件
bool TableModelDemo::removeRows(int row, int count, const QModelIndex &parent /*= QModelIndex()*/)
{
beginRemoveRows(parent, row, row + count - 1);
for (int i = row + count - 1; i >= row; --i)
{
m_list.removeAt(i);
}
endRemoveRows();
return true;
}
③.刪除末尾行
connect(ui.pushButton, &QPushButton::clicked, [mode]() {
mode->removeRows(m_list.size()-1, 1);//刪除末尾行
});