Читаем QT 4: программирование GUI на С++ полностью

12 QString currencyAt(int offset) const;

13 QMap currencyMap;

14 };

Для нашей модели мы использовали подкласс QAbstractTableModel, поскольку он лучше всего подходит к нашему источнику данных. Qt содержит несколько базовых классов моделей, включая QAbstractListModel, QAbstractTableModel и QAbstractItemModel. Класс QAbstractItemModel используется для поддержки разнообразных моделей, в том числе тех, которые построены на рекурсивных структурах данных, а классы QAbstractListModel и QAbstractTableModel удобно применять для одномерных и двумерных наборов данных.

Рис. 10.11. Дерево наследования для абстрактных классов моделей.

Для модели таблицы, используемой только для чтения, мы должны переопределить три функции: rowCount, columnCount и data. В данном случае мы также переопределили функцию headerData и обеспечили функцию инициализации данных (setCurrencyMap).

01 CurrencyModel::CurrencyModel(QObject*parent)

02 : QAbstractTableModel(parent)

03 {

04 }

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

01 int CurrencyModel::rowCount(const QModelIndex &

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

03 {

04 return currencyMap.count;

05 }

06 int CurrencyModel::columnCount(const QModelIndex &

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

08 {

09 return currencyMap.count;

10 }

В этой табличной модели счетчики строк и столбцов представляют собой номера валют в ассоциативном массиве валют. Параметр parent не имеет смысла в модели таблицы; он здесь указан, потому что rowCount и columnCount наследуются от более обобщенного базового класса QAbstractItemModel, поддерживающего иерархические структуры.

01 QVariant CurrencyModel::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 QString rowCurrency = currencyAt(index.row);

09 QString columnCurrency = currencyAt(index.column);

10 if (currencyMap.value(rowCurrency) == 0.0)

11 return "####";

12 double amount = currencyMap.value(columnCurrency)

13 / currencyMap.value(rowCurrency);

14 return QString("%1").arg(amount, 0, 'f', 4);

15 }

16 return QVariant;

17 }

Функция data возвращает значение любой одной роли элемента. Элемент определяется индексом QModelIndex. В модели таблицы представляют интерес такие компоненты QModelIndex, как номер строки и номер столбца, получить доступ к которым можно с помощью функций row и column.

Если используется роль Qt::TextAlignmentRole, мы возвращаем значение, подходящее для выравнивания чисел. Если используется роль Qt::DisplayRole, мы находим значение каждой валюты и вычисляем курс обмена.

Мы могли бы возвращать рассчитанное значение типа double, но тогда нам пришлось бы контролировать количество позиций после десятичной точки при отображении числа (если мы не используем пользовательский делегат). Вместо этого мы возвращаем значение в виде строки, отформатированной нужным нам образом.

01 QVariant CurrencyModel::headerData(int section,

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

03 {

04 if (role != Qt::DisplayRole)

05 return QVariant;

06 return currencyAt(section);

07 }

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже