使用背景
随着开发项目的不断增大,业务结构越来越复杂,为了提高程序员的开发效率和降低维护成本(代码的可读性),在QT中使用MVC(MVD)模式是行之有效的方法。而自定义Model则是使用MVC模式的第一步。
如何自定义
QT给我们预定义了许多model,view和delegate,也就是说我们可以很方便快速的继承相应的类完成开发。我们只需要遵循相关的规范,实现一些特定的方法便可以完成自定义Model类。
步骤:以QAbstractTableModel为例
- 新建一个C++类,生成头文件和cpp文件
- 在头文件类定义中继承QAbstractTableModel类,并且重写以下函数
- virtual int rowCount(const QModelIndex &parent) const;
- virtual int columnCount(const QModelIndex &parent) const;
- QVariant data(const QModelIndex &index, int role) const;
- QVariant headerData(int section, Qt::Orientation orientation, int role) const;
- 在头文件中定义自己需要的数据类型
- 在cpp文件中初始化自己的数据类型,并且实现以上方法,参考下面的代码
Demo
header:
#ifndef MODELEX_H
#define MODELEX_H
#include <QAbstractTableModel>
#include <QVector>
#include <QMap>
#include <QStringList>
class ModelEx :public QAbstractTableModel
{
public:
ModelEx();
//声明虚函数
virtual int rowCount(const QModelIndex &parent) const;
virtual int columnCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
signals:
public slots:
private:
QVector<short> army;
QVector<short> weaponType;
QMap<short,QString>armyMap;
QMap<short,QString> weaponTypeMap;//武器种类对应关系
QStringList weapon;//武器列表
QStringList header;
void populateModel();//初始化函数
};
#endif // MODELEX_H
cpp:
#include "modelex.h"
#include <QDebug>
ModelEx::ModelEx()
{
//初始化数值 文字对应关系
armyMap[1] = "海军";
armyMap[2] = "空军";
armyMap[3] = "陆军";
armyMap[4] = "海军陆战队";
weaponTypeMap[1] = "轰炸机";
weaponTypeMap[2] = "战斗机";
weaponTypeMap[3] = "航空母舰";
weaponTypeMap[4] = "驱逐舰";
weaponTypeMap[5] = "直升机";
weaponTypeMap[6] = "TANKE";
weaponTypeMap[7] = "两栖战车";
weaponTypeMap[8] ="都是我瞎编的";
populateModel();
}
void ModelEx::populateModel(){
header<<"军种"<<"种类"<<"武器";//表头信息
army<<1<<2<<3<<4<<4<<2<<3;
weaponType<<1<<6<<3<<7<<4<<8<<2;//数值和文字是怎么转化的
weapon<<"B--2"<<"A-2"<<"D-!qaew"<<"B--2"<<"A-2"<<"D-!qaew"<<"B--2";
}
//返回模型的列数
int ModelEx::columnCount(const QModelIndex &parent) const{
return header.size();
}
int ModelEx::rowCount(const QModelIndex &parent) const{
return army.size();
}
//返回指定索引的数据,即将数值映射为文字
QVariant ModelEx::data(const QModelIndex &index, int role) const{
if(!index.isValid()){
return QVariant();
}
if(role==Qt::DisplayRole){
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();
break;
}
}
return QVariant();
}
QVariant ModelEx::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);
}
测试:
#include "qmodeldialog.h"
#include <QApplication>
#include <QTableView>
#include "modelex.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// QModelDialog w;
// w.show();
ModelEx *model = new ModelEx();
QTableView view;
view.setModel(model);
view.setWindowTitle("ModelEx");
view.resize(400,300);
view.show();
return a.exec();
}
Qt5开发及实例,第三版 ,电子工业出版社——陆文同