自定义模型CityModel
参考<<C++ GUI Programming with Qt 4>>中文版第二版中的例子:城市距离。具体描述请看书本,主要重写继承自QAbstractTableModel的CityModel,该模型底层的数据是一个QStringList类型的对象和一个QVector<int>类型的对象。前者用于保存城市的名字,后者保存城市之间的距离。
citymodel.h文件:
#ifndef CITYMODEL_H #define CITYMODEL_H #include <QAbstractTableModel> #include <QVector> #include <QStringList> class CityModel : public QAbstractTableModel { 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
citymodel.cpp文件:
#include "citymodel.h" CityModel::CityModel(QObject *parent) :QAbstractTableModel(parent) { } 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 { 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(); } QVariant CityModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role == Qt::DisplayRole) { return cities[section]; } 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; } Qt::ItemFlags CityModel::flags(const QModelIndex &index) const { Qt::ItemFlags flags = QAbstractItemModel::flags(index); if (index.row() != index.column()) { flags |= Qt::ItemIsEditable; } return flags; } void CityModel::setCities(const QStringList &cityNames) { cities = cityNames; distances.resize(cities.count() * (cities.count() - 1)/2); distances.fill(0); reset(); } int CityModel::offsetOf(int row, int column) const { if (row < column) { qSwap(row, column); } return (row * (row - 1)/2) + column; }
main.cpp文件:
#include <QtGui/QApplication> #include "citymodel.h" #include <QTableView> int main(int argc, char *argv[]) { QApplication a(argc, argv); QStringList cities; cities<<"Arvika"<<"Boden"<<"Eskilstuna"<<"Falun"<<"Filipstad"; CityModel cityModel; cityModel.setCities(cities); QTableView tableView; tableView.setModel(&cityModel); tableView.setAlternatingRowColors(true); tableView.setWindowTitle("cities"); tableView.show(); return a.exec(); }
运行界面: