qt预定义的模型微数据的处理和查看提供了很好的方法,但是对于数据源不能和预定义的模型一起工作,这是就需要自己定制自定义模型,在模型中每一个数据元素都有一个模型索引和一套属性,称为角色。这些角色可以保存任意值。常用的角色有Qt::displayRole,Qt::EditRole:
树模型和表模型比较相似,但有不同之处,对于表每一项的父对象都是根对象 ,但对于树来说就不一定每一个qmodelInde();都有自己的角色和数据,可能有子对象,子对象通过modelIndex.parent()获得。
/--------------头函数----------------/
#ifndef CITYMODEL_H
#define CITYMODEL_H
#include <QAbstractTableModel>
#include <QStringList>
#include <QVector>
class CityModel : public QAbstractTableModel
{
Q_OBJECT
public:
CityModel(QObject *parent = 0);
void setCities(const QStringList &cityNames);
int rowCount(const QModelIndex &parent) const;//行数
int columnCount(const QModelIndex &parent) const;//列数
QVariant data(const QModelIndex &index, int role) const;//角色数据获取
bool setData(const QModelIndex &index, const QVariant &value,
int role);
QVariant headerData(int section, Qt::Orientation orientation,
int role) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
private:
int offsetOf(int row, int column) const;
QStringList cities;
QVector<int> distances;
};
#endif
/--------------原函数--------------/
#include <QtCore>
#include "citymodel.h"
#include<qtwidgets/QtWidgets>
CityModel::CityModel(QObject *parent)
: QAbstractTableModel(parent)
{
}
void CityModel::setCities(const QStringList &cityNames)
{
cities = cityNames;
distances.resize(cities.count() * (cities.count() - 1) / 2);//定义数据的个数
distances.fill(0);
// reset();
}
int CityModel::rowCount(const QModelIndex & /* parent */) const
{
return cities.count();
}
int CityModel::columnCount(const QModelIndex & /* parent */) const
{
return cities.count();
}
QVariant CityModel::data(const QModelIndex &index, int role) const//获取index数据
{
if (!index.isValid())
return QVariant();
if (role == Qt::TextAlignmentRole) {
return int(Qt::AlignRight | Qt::AlignVCenter);
} else if (role == Qt::DisplayRole) {
if (index.row() == index.column())
return 0;
int offset = offsetOf(index.row(), index.column());
return distances[offset];
}
return QVariant();
}
bool CityModel::setData(const QModelIndex &index,
const QVariant &value, int role)
{
if (index.isValid() && index.row() != index.column()
&& role == Qt::EditRole) {
int offset = offsetOf(index.row(), index.column());//获取位置
distances[offset] = value.toInt();
QModelIndex transposedIndex = createIndex(index.column(),
index.row());
emit dataChanged(index, index);
emit dataChanged(transposedIndex, transposedIndex);
return true;
}
return false;
}
QVariant CityModel::headerData(int section,
Qt::Orientation /* orientation */,
int role) const
{
if (role == Qt::DisplayRole)
return cities[section];
return QVariant();
}
Qt::ItemFlags CityModel::flags(const QModelIndex &index) const
{//获取对话ditem是否可编辑
Qt::ItemFlags flags = QAbstractItemModel::flags(index);
if (index.row() != index.column())
flags |= Qt::ItemIsEditable;
return flags;
}
int CityModel::offsetOf(int row, int column) const
{
if (row < column)
qSwap(row, column);
return (row * (row - 1) / 2) + column;
}/-----------------头函数---------------------/
#include <qtwidgets/QApplication>
#include <qtwidgets/QHeaderView>
#include <qtwidgets/QTableView>
#include "citymodel.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QStringList cities;
cities << "Arvika" << "Boden" << "Eskilstuna" << "Falun"
<< "Filipstad" << "Halmstad" << "Helsingborg" << "Karlstad"
<< "Kiruna" << "Kramfors" << "Motala" << "Sandviken"
<< "Skara" << "Stockholm" << "Sundsvall" << "Trelleborg";
CityModel cityModel;
cityModel.setCities(cities);
QTableView tableView;
tableView.setModel(&cityModel);
tableView.setAlternatingRowColors(true);
tableView.setWindowTitle(QObject::tr("Cities"));
tableView.show();
return app.exec();
}