16 int offsetOf(int row, int column) const;

17 QStringList cities;

18 QVector distanсes;

19 };

В этой модели мы используем две структуры данных: cities типа QStringList для хранения названий городов, и distances типа QVector для хранения расстояний между городами каждой уникальной пары.

01 CityModel::CityModel(QObject *parent)

02 : QAbstractTableModel(parent)

03 {

04 }

Конструктор передает параметр parent базовому классу и больше ничего не делает.

01 int CityModel::rowCount(const QModelIndex &

02 /* родительский элемент */) const

03 {

04 return cities.count();

05 }

06 int CityModel::columnCount(const QModelIndex &

07 /* родительский элемент */) const

08 {

09 return cities.count();

10 }

Поскольку мы имеем квадратную матрицу городов, количество строк и столбцов равно количеству городов в нашем списке.

01 QVariant CityModel::data(const QModelIndex &index, int role) const

02 {

03 if (!index.isValid())

04 return QVariant();

05 if (role == Qt::TextAlignmentRole) {

06 return int(Qt::AlignRight | Qt::AlignVCenter);

07 } else if (role == Qt::DisplayRole) {

08 if (index.row() == index.column())

09 return 0;

10 int offset = offsetOf(index.row(), index.column());

11 return distances[offset];

12 }

13 return QVariant();

14 }

Функция data() аналогична той же функции в нашей модели CurrencyModel. Она возвращает 0, если строка и столбец имеют одинаковый номер, потому что в этом случае два города одинаковы; в противном случае она находит в векторе distances элемент для заданной строки и заданного столбца, возвращая расстояние для этой конкретной пары городов.

01 QVariant CityModel::headerData(int section,

02 Qt::Orientation /* ориентация */,

03 int role) const

04 {

05 if (role == Qt::DisplayRole)

06 return cities[section];

07 return QVariant();

08 }

Функция headerData() имеет простой вид, потому что наша таблица является квадратной матрицей, в которой строки и столбцы имеют идентичные заголовки. Мы просто возвращаем название города, расположенное с заданным смещением в списке строк cities.

01 bool CityModel::setData(const QModelIndex &index,

02 const QVariant &value, int role)

03 {

04 if (index.isValid() && index.row() != index.column()

05 && role == Qt::EditRole) {

06 int offset = offsetOf(index.row(), index.column());

07 distances[offset] = value.toInt();

08 QModelIndex transposedIndex = createIndex(

09 index.column(), index.row());

10 emit dataChanged(index, index);

11 emit dataChanged(transposedIndex, transposedIndex);

12 return true;

13 }

14 return false;

15 }

Функция setData() вызывается при редактировании элемента пользователем. Если индекс модели действителен, два города различны и модифицируемый элемент данных имеет ролевой атрибут Qt::EditRole, эта функция сохраняет введенное пользователем значение в векторе distances.

Перейти на страницу:

Похожие книги