背景
Qt 模型视图编程中模型定义了标准接口对数据进行访问,可根据需求继承对应的抽象模型类来实现自定义的数据模型。一个基本的数据模型至少要实现以下虚函数:
①.rowCount:行数,返回要显示多少行;
②.columnCount:列数,返回要显示多少列
③.data:读取数据,返回每个单元格要显示的内容
视图不会主动更新数据的显示,模型使用 dataChanged 信号通知视图数据发生变化。
表头相关接口
①.概述
在视图界面中除了显示数据外,还包含了横向、纵向两个表头的显示;在数据模型中也提供了对表头进行设置的接口。
②.关键虚函数
headerData:数据模型对外提供的获取表头显示内容的接口;
setHeaderData:数据模型对外提供的可设置表头的内容的接口。
③.表头更新信号
headerDataChanged:表头内容更新信号,通知界面更新显示。
④.默认表头内容
横向和纵向表头默认值显示为对应的行号和列号,从 1 开始;当不需自定义表头内容时,直接调用基类的方法返回其默认实现即可。
设置模型表头内容
①.概述
一般在用于数据显示时其表头内容在初始化时设定好即可,通常无需变动。
②.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, QList<QString> & headers, QObject *parent = nullptr):QAbstractTableModel(parent),m_list(list),m_header(headers){};
~TableModelDemo() {};
public:
int rowCount(const QModelIndex &parent) const override { return m_list.size(); }//行数
int columnCount(const QModelIndex &parent) const override { return m_header.size(); }//列数
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;//
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;//获取表头
private:
QList<student> &m_list;//对内存中数据的引用
QList<QString> m_header;//表头内容
public:
void setCustomData(QList<student> & l);
void setHeaderData(QList<QString> & headers);
};
③.TableModelDemo.cpp 文件
QVariant TableModelDemo::headerData(int section, Qt::Orientation orientation, int role /*= Qt::DisplayRole*/) const
{
if (orientation == Qt::Horizontal)//只更改横向表头
{
switch (role)
{
case Qt::DisplayRole:
return m_header[section];
default:
break;
}
}
return QAbstractTableModel::headerData(section, orientation, role);//返回默认实现
}
④.数据模型初始化
student s;
s.age = 18;
s.name = "张三";
s.sex = "男";
m_list.append(s);
s.age = 16;
s.name = "李四";
s.sex = "女";
m_list.append(s);
QList<QString> m_header{ "姓名","年龄","性别" };
auto mode = new TableModelDemo(m_list, m_header);
ui.tableView->setModel(mode);
更改模型表头内容
①.更改单个表头内容
通过 setHeaderData 可以设置单个表头内容的显示,并通过信号通知视图刷新显示:
bool TableModelDemo::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role /*= Qt::EditRole*/)
{
if (orientation == Qt::Horizontal)
{
m_header[section] = value.toString();
emit headerDataChanged(orientation, section, section);
return true;
}
return false;
}
②.更改整个表头内容
当视图关联的模型变更时,通常也需要对其表头内容进行对应更改:
void TableModelDemo::setCustomData(QList<student> & l)
{
int m_rowCount = rowCount(QModelIndex());
int m_colCount = columnCount(QModelIndex());
m_list = l;
emit dataChanged(index(0, 0), index(m_rowCount - 1, m_rowCount - 1));
}