目錄:
(一) Qt Model/View 的簡單說明 、預定義模型
(二)使用預定義模型 QstringListModel例子
(三)使用預定義模型QDirModel的例子
(四)Qt實作自定義模型基于QAbstractTableModel
(五)Qt實作自定義模型基于QAbstractItemModel
(六) Qt實作自定義委托 QDelegate
Qt實作自定義模型基于QAbstractTableModel
兩個例子
例子1代碼
Main.cpp
#include <QtGui>
#include "currencymodel.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
//資料源
QMap<QString, double> currencyMap;
currencyMap.insert("AUD", 1.3259);
currencyMap.insert("CHF", 1.2970);
currencyMap.insert("CZK", 24.510);
currencyMap.insert("DKK", 6.2168);
currencyMap.insert("EUR", 0.8333);
currencyMap.insert("GBP", 0.5661);
currencyMap.insert("HKD", 7.7562);
currencyMap.insert("JPY", 112.92);
currencyMap.insert("NOK", 6.5200);
currencyMap.insert("NZD", 1.4697);
currencyMap.insert("SEK", 7.8180);
currencyMap.insert("SGD", 1.6901);
currencyMap.insert("USD", 1.0000);
//自定義表模型
CurrencyModel currencyModel;
currencyModel.setCurrencyMap(currencyMap);
//表視圖
QTableView tableView;
//設定視圖模型
tableView.setModel(¤cyModel);
//設定交替顔色
tableView.setAlternatingRowColors(true);
tableView.setWindowTitle(QObject::tr("Currencies"));
tableView.show();
return app.exec();
}
currencymodel.h
#ifndef CURRENCYMODEL_H
#define CURRENCYMODEL_H
#include <QAbstractTableModel>
#include <QMap>
class CurrencyModel : public QAbstractTableModel
{
public:
CurrencyModel(QObject *parent = 0);
void setCurrencyMap(const QMap<QString, double> &map);
int rowCount(const QModelIndex &parent) const;
int columnCount(const QModelIndex &parent) const;
QVariant data(const QModelIndex &index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation,
int role) const;
private:
QString currencyAt(int offset) const;
QMap<QString, double> currencyMap;
};
#endif
currencymodel.cpp
#include <QtCore>
#include "currencymodel.h"
CurrencyModel::CurrencyModel(QObject *parent)
: QAbstractTableModel(parent)
{
}
void CurrencyModel::setCurrencyMap(const QMap<QString, double> &map)
{
currencyMap = map;
//重置模型至原始狀态,告訴所有視圖,他們資料都無效,強制重新整理資料
reset();
}
//傳回行數
int CurrencyModel::rowCount(const QModelIndex & /* parent */) const
{
return currencyMap.count();
}
//傳回列數
int CurrencyModel::columnCount(const QModelIndex & /* parent */) const
{
return currencyMap.count();
}
//傳回一個項的任意角色的值,這個項被指定為QModelIndex
QVariant CurrencyModel::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) {
QString rowCurrency = currencyAt(index.row());
QString columnCurrency = currencyAt(index.column());
if (currencyMap.value(rowCurrency) == 0.0)
return "####";
double amount = currencyMap.value(columnCurrency)
/ currencyMap.value(rowCurrency);
return QString("%1").arg(amount, 0, 'f', 4);
}
return QVariant();
}
//傳回表頭名稱,(行号或列号,水準或垂直,角色)
QVariant CurrencyModel::headerData(int section,
Qt::Orientation /* orientation */,
int role) const
{
if (role != Qt::DisplayRole)
return QVariant();
return currencyAt(section);
}
//擷取目前關鍵字
QString CurrencyModel::currencyAt(int offset) const
{
return (currencyMap.begin() + offset).key();
}
例子2代碼
Main.cpp
#include <QApplication>
#include <QHeaderView>
#include <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();
}
citymodel.h
#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
citymodel.cpp
#include <QtCore>
#include "citymodel.h"
CityModel::CityModel(QObject *parent)
: QAbstractTableModel(parent)
{
}
//設定一下資料源
void CityModel::setCities(const QStringList &cityNames)
{
cities = cityNames;
//重新設定一下QVector distances的矩陣大小的,中間對角線為0不用存
distances.resize(cities.count() * (cities.count() - 1) / 2);
//填充所有距離值為0
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
{
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());
//某項發生改變,發射信号( between topLeft and bottomRight inclusive)
emit dataChanged(index, index);
emit dataChanged(transposedIndex, transposedIndex);
return true;
}
return false;
}
//傳回清單頭
QVariant CityModel::headerData(int section,
Qt::Orientation /* orientation */,
int role) const
{
//傳回在Cities字元串清單中給定偏移量的城市名稱
if (role == Qt::DisplayRole)
return cities[section];
return QVariant();
}
//傳回對一個項相關的操作的辨別符(例如,是否可以編輯或者是否已選中等)
Qt::ItemFlags CityModel::flags(const QModelIndex &index) const
{
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;
}