实现自定义模型可以通过QAbstractItemModel类继承,也可以通过QAbstractListModel和QAbstractTableModel类继承实现列表模型或者表格模型。
在数据库中,通常需要首先将一些复杂的文字字段使用数据代码保存,然后通过外键关联操作来查找其真实的含义,这一方法是为了避免冗余。
一、效果展示
二、具体代码
modelexample.h
#ifndef MODELEXAMPLE_H
#define MODELEXAMPLE_H
#include <QAbstractTableModel>
#include <QVector>
#include <QMap>
#include <QStringList>
class ModelExample : public QAbstractTableModel
{
public:
explicit ModelExample(QObject *parent = 0);
//虚函数声明
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
private:
QVector<short> army;
QVector<short> weaponType;
QMap<short,QString> armyMap;
QMap<short,QString> weaponTypeMap;
QStringList weapon;
QStringList header;
void populateModel();
};
#endif // MODELEXAMPLE_H
注意:rowCount()、columnCount()、data()和返回表头数据的headerData()函数
是QAbstractTableModel类的纯虚函数。
modelexample.cpp
#include "modelexample.h"
ModelExample::ModelExample(QObject *parent) : QAbstractTableModel(parent)
{
armyMap[1]=tr("空军");
armyMap[2]=tr("海军");
armyMap[3]=tr("陆军");
armyMap[4]=tr("海军陆站队");
weaponTypeMap[1]=tr("轰战机");
weaponTypeMap[2]=tr("战斗机");
weaponTypeMap[3]=tr("航空母舰");
weaponTypeMap[4]=tr("驱逐舰");
weaponTypeMap[5]=tr("直升机");
weaponTypeMap[6]=tr("坦克");
weaponTypeMap[7]=tr("两栖攻击舰");
weaponTypeMap[8]=tr("两栖战车");
populateModel();
}
void ModelExample::populateModel()
{
header<<tr("军种")<<tr("种类")<<tr("武器");
army<<1<<2<<3<<4<<2<<4<<3<<1;
weaponType<<1<<3<<5<<7<<4<<8<<6<<2;
weapon<<tr("B-2")<<tr("尼米磁级")<<tr("阿帕奇")<<tr("黄蜂级")<<tr("阿利伯克级")<<tr("AAAV")<<tr("M1A1")<<tr("F-22");
}
int ModelExample::columnCount(const QModelIndex &parent) const
{
return 3;
}
int ModelExample::rowCount(const QModelIndex &parent) const
{
return army.size();
}
QVariant ModelExample::data(const QModelIndex &index, int role) const
{
if(!index.isValid())
return QVariant();
if(role==Qt::DisplayRole) //(a)
{
switch (index.column()) {
case 0:
return armyMap[army[index.row()]];
break;
case 1:
return weaponTypeMap[weaponType[index.row()]];
break;
case 2:
return weapon[index.row()];
break;
default:
return QVariant();
}
}
return QVariant();
}
QVariant ModelExample::headerData(int section, Qt::Orientation orientation, int role) const
{
if(role==Qt::DisplayRole && orientation==Qt::Horizontal)
{
return header[section];
}
return QAbstractTableModel::headerData(section,orientation,role);
}
注意:
(a):role==Qt::DisplayRole
:模型中的条目能够有不同的角色,这样可以在不同的情况下提供不同的数据。例如,Qt::DisplayRole用来存取视图中显示的文字,角色由枚举类Qt::ItemDataRole定义。
下表列出了Item主要的角色及其描述:
常量 | 描述 |
---|---|
Qt::DisplayRole | 显示文字 |
Qt::DecorationRole | 绘制装饰数据(通常是图标) |
Qt::EditRole | 在编辑器中编辑的数据 |
Qt::ToolTipRole | 工具提示 |
Qt::StatusTipRole | 状态栏提示 |
Qt::WhatsThisRole | What’s This文字 |
Qt::SizeHintRole | 尺寸提示 |
Qt::FontRole | 默认代理的绘制使用的字体 |
Qt::TextAlignmentRole | 默认代理的对齐方式 |
Qt::BackgroundRole | 默认代理的背景画刷 |
Qt::ForegroundRole | 默认代理的前景画刷 |
Qt::CheckStateRole | 默认代理的检查框状态 |
Qt::UserRole | 用户自定义的数据的起始位置 |
main.cpp |
#include "modelexample.h".h"
#include <QApplication>
#include <QTableView>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ModelExample modelEx;
QTableView view;
view.setModel(&modelEx);
view.setWindowTitle(QObject::tr("ModelEx"));
view.resize(400,400);
view.show();
return a.exec();
}