QTableWidget содержит несколько дочерних виджетов. Сверху располагается горизонтальный заголовок QHeaderView, слева — вертикальный заголовок QHeaderView и две полосы прокрутки QScrollBar. В центральной области размещается специальный виджет, называемый областью отображения (viewport), в котором QTableWidget вычерчивает ячейки. Доступ к различным дочерним виджетам осуществляется с помощью функций, унаследованных от QTableView и QAbstractScrollArea (рис. 4.2). QAbstractScrollArea содержит перемещаемую область отображения и две полосы прокрутки, которые могут включаться и отключаться. Подкласс QScrollArea рассматривается в главе 6.
Хранение данных в объектах типа «элемент»
В приложении Электронная таблица каждая непустая ячейка хранится в памяти в виде одного объекта QTableWidgetltem (элемент табличного виджета). Хранение данных в объектах типа «элемент» используется также виджетами QListWidget и QTreeWidget, которые работают с объектами QListWidgetItem и QTreeWidgetItem.
В Qt классы элементов могут использоваться вне таблиц как самостоятельные структуры данных. Например, QTableWidgetltem уже содержит некоторые атрибуты, в том числе строку, шрифт, цвет и пиктограмму, а также обратный указатель на QTableWidget. Такие элементы могут содержать также данные типа QVariant, включая зарегистрированные пользовательские типы, и, создавая подкласс такого элемента, можно обеспечить дополнительную функциональность.
Другие инструментальные средства предусматривают наличие в классах элементов указателя типа void для хранения пользовательских данных. В Qt используется более естественный подход с применением setData для типа QVariant, однако если требуется иметь указатель void, это можно сделать просто путем создания подкласса для класса элемента, который будет содержать переменную—указатель на член типа void.
Для данных, к которым предъявляются повышенные требования, например для больших наборов данных, для сложных элементов данных, для интеграции баз данных и для множественных представлений данных, Qt предоставляет набор классов «модель/представление», в которых данные отделены от их визуального представления. Эти классы рассматриваются в главе 10.
01 Cell *Spreadsheet::cell(int row, int column) const
02 {
03 return static_cast(item(row, column)); |
04 }
Закрытая функция cell возвращает для заданной строки и столбца объект Cell. Она работает почти так же, как QTableWidget::item, но возвращает указатель на Cell, а не указатель на QTableWidgetltem.
01 QString Spreadsheet::text(int row, int column) const
02 {
03 Cell *c = cell(row, column);
04 if (с) {
05 return c->text;
06 } else {
07 return "";
08 }
09 }
Закрытая функция text возвращает формулу заданной ячейки. Если cell возвращает нулевой указатель, то это означает, что ячейка пустая, и поэтому мы возвращаем пустую строку.
01 QString Spreadsheet::formula(int row, int column) const
02 {
03 Cell *c = cell(row, column);
04 if (с) {
05 return c->formula;
06 } else {
07 return "";
08 }
09 }
Функция formula возвращает формулу ячейки. Во многих случаях формула и текст совпадают; например формула «Hello» соответствует строке «Hello», поэтому при вводе пользователем в ячейку строки «Hello» и нажатии клавиши Enter в ячейке отобразится текст «Hello». Но имеется несколько исключений:
• Если формула представлена числом, именно оно и будет отображаться. Например, формула «1.50» обозначает значение 1.5 типа double, которое отображается в электронной таблице как выровненное вправо значение «1.5».
• Если формула начинается с одиночной кавычки, остальная часть формулы интерпретируется как текст. Например, результатом формулы «'12345» будет строка «12345».
• Если формула начинается со знака равенства («=»), то ее значение интерпретируется как арифметическое выражение. Например, если ячейка A1 содержит «12» и ячейка A2 содержит «6», то результатом формулы «=A1+A2» будет 18. Задача преобразования формулы в значение выполняется классом Cell. Здесь следует иметь в виду, что отображаемый в ячейке текст соответствует значению, полученному в результате расчета формулы, а не является текстом самой формулы.