35 enum { MagicNumber = 0x7F51C883, RowCount = 999, ColumnCount = 26 };

36 Cell *cell(int row, int column) const;

37 QString text(int row, int column) const;

38 QString formula(int row, int column) const;

39 void setFormula(int row, int column, const QString &formula);

40 bool autoRecalc;

41 };

В закрытой секции этого класса мы объявляем три константы, четыре функции и одну переменную.

42 class SpreadsheetCompare

43 {

44 public:

45 bool operator(const QStringList &row1, const QStringList &row2) const;

46 enum { KeyCount = 3 };

47 int keys[KeyCount];

48 bool ascending[KeyCount];

49 };

50 #endif

Заголовочный файл заканчивается определением класса SpreadsheetCompare. Мы объясним назначение этого класса при рассмотрении функции Spreadsheet::sort.

Теперь мы рассмотрим реализацию:

01 #include

02 #include "cell.h"

03 #include "spreadsheet.h"

04 Spreadsheet::Spreadsheet(QWidget *parent)

05 : QTableWidget(parent)

06 {

07 autoRecalc = true;

08 setItemPrototype(new Cell);

09 setSelectionMode(ContiguousSelection);

10 connect(this, SIGNAL(itemChanged(QTableWidgetItem *)),

11 this, SLOT(somethingChanged));

12 clear;

13 }

Обычно при вводе пользователем некоторого текста в пустую ячейку QTableWidget будет автоматически создавать элемент QTableWidgetltem для хранения этого текста. Вместо этого мы хотим, чтобы создавались элементы Cell. Это достигается с помощью вызова в конструкторе функции setItemPrototype. Всякий раз, когда требуется новый элемент, QTableWidget дублирует элемент, переданный в качестве прототипа.

Кроме того, в конструкторе мы устанавливаем режим выделения области на значение QAbstractItemView::ContiguousSelection, чтобы могла быть выделена только одна прямоугольная область. Мы соединяем сигнал itemChanged виджета таблицы с закрытым слотом somethingChanged; это гарантирует вызов слота somethingChanged при редактировании ячейки пользователем. Наконец, мы вызываем clear для изменения размеров таблицы и задания заголовков столбцов.

14 void Spreadsheet::clear

15 {

16 setRowCount(0);

17 setColumnCount(0);

18 setRowCount(RowCount);

19 setColumnCount(ColumnCount);

20 for (int i = 0; i < ColumnCount; ++i) {

21 QTableWidgetltem *item = new QTableWidgetltem;

22 item->setText(QString(QChar('A' + i)));

23 setHorizontalHeaderItem(i, item);

24 }

25 setCurrentCell(0, 0);

26 }

Функция clear вызывается из конструктора Spreadsheet для инициализации электронной таблицы. Она также вызывается из MainWindow::newFile.

Мы могли бы использовать QTableWidget::clear для очистки всех элементов и любых выделений, но в этом случае заголовки имели бы текущий размер. Вместо этого мы уменьшаем размер электронной таблицы до 0 × 0. Это приводит к очистке всей электронной таблицы, включая заголовки. Затем мы опять устанавливаем ее размер на ColumnCount × RowCount (26 × 999) и заполняем строку горизонтального заголовка элементами QTableWidgetltem, содержащими обозначения столбцов. Нам не надо задавать метки строк, потому что по умолчанию строки обозначаются как «1», «2», … «26». В конце мы перемещаем курсор на ячейку A1.

Рис. 4.2. Виджеты, составляющие QTableWidget.

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