Саммерфилд Марк - QT 4: программирование GUI на С++ стр 24.

Шрифт
Фон

08 clearSelection();

09 setCurrentCell(row, column);

10 activateWindow();

11 return;

12 }

13 ++column;

14 }

15 column = 0;

16 ++row;

17 }

18 QApplication::beep();

19 }

Слот findNext() в цикле просматривает ячейки, начиная с ячейки, расположенной правее курсора, и двигается вправо до достижения последнего столбца; затем процесс идет с первого столбца строки, расположенной ниже, и так продолжается, пока не будет найден требуемый текст или пока не будет достигнута самая последняя ячейка. Например, если текущей является ячейка C24, поиск будет продолжаться по ячейкам D24, E24, Z24, затем no A25, B25, C25, Z25 и так далее, пока не будет достигнута ячейка Z999. Если соответствующее значение найдено, мы сбрасываем текущее выделение и перемещаем курсор на ячейку, в которой оно находится, и делаем активным окно, содержащее эту электронную таблицу Spreadsheet. При неудачном завершении поиска мы заставляем приложение выдать соответствующий звуковой сигнал.

01 void Spreadsheet::findPrevious(const QString &str, Qt::CaseSensitivity cs)

02 {

03 int row = currentRow();

04 int column = currentColumn() - 1;

05 while (row>= 0) {

06 while (column >= 0) {

07 if (text(row, column).contains(str, cs)) {

08 clearSelection();

09 setCurrentCell(row, column);

10 activateWindow();

11 return;

12 }

13 --column;

14 }

15 column = ColumnCount - 1;

16 --row;

17 }

18 QApplication::beep();

19 }

Слот findPrevious() похож на findNext(), но здесь цикл выполняется в обратном направлении и заканчивается в ячейке A1.

Реализация других меню

Рис. 4.7. Меню Tools и Options приложения Электронная таблица.

01 void Spreadsheet::recalculate()

02 {

03 for (int row = 0; row < RowCount; ++row) {

04 for (int column = 0; column < ColumnCount; ++column) {

05 if (cell(row, column))

06 cell(row, column)->setDirty();

07 }

08 }

09 viewport()->update();

10 }

Слот recalculate() соответствует пункту меню Tools | Recalculate (Инструменты | Пересчитать). Он также вызывается в Spreadsheet автоматически по мере необходимости.

Мы выполняем цикл по всем ячейкам и вызываем функцию setDirty(), которая помечает каждую из них для перерасчета значения. В следующий раз, когда QTableWidget для получения отображаемого в электронной таблице значения вызовет text() для некоторой ячейки Cell, значение этой ячейки будет пересчитано.

Затем мы вызываем для области отображения функцию update() для перерисовки всей электронной таблицы. При этом используемый в QTableWidget программный код по перерисовке вызывает функцию text() для каждой видимой ячейки для получения отображаемого значения. Поскольку функция setDirty() вызывалась нами для каждой ячейки, в вызовах text() будет использовано новое рассчитанное значение. В этом случае может потребоваться расчет невидимых ячеек, который будет проводиться до тех пор, пока не будут рассчитаны все ячейки, влияющие на правильное отображение текста в перерассчитанной области отображения. Этот расчет выполняется в классе Cell.

01 void Spreadsheet::setAutoRecalculate(bool recalc)

02 {

03 autoRecalc = recalc;

04 if (autoRecalc)

05 recalculate();

06 }

Слот setAutoRecalculate() соответствует пункту меню Options | AutoRecalculate. Если эта опция включена, мы сразу же пересчитаем всю электронную таблицу и будем уверены, что она показывает обновленные значения; впоследствии функция recalculate() будет автоматически вызываться из somethingChanged().

Нам не нужно реализовывать специальную функцию для пункта меню Options | Show Grid, поскольку в QTableWidget уже содержится слот setShowGrid(), который наследуется от базового класса QTableView. Остается только реализовать функцию Spreadsheet::sort(), которая вызывается из MainWindow::sort():

01 void Spreadsheet::sort(const SpreadsheetCompare &compare)

02 {

03 QList<QStringList> rows;

04 QTableWidgetSelectionRange range = selectedRange();

05 int i;

06 for (i = 0; i < range.rowCount(); ++i) {

07 QStringList row;

08 for (int j = 0; j < range.columnCount(); ++j)

09 row.append(formula(range.topRow() + i,

10 range.leftColumn() + j));

11 rows.append(row);

12 }

13 qStableSort(rows.begin(), rows.end(), compare);

14 for (i = 0; i < range.rowCount(); ++i) {

15 for (int j = 0; j < range.columnCount(); ++j)

16 setFormula(range.topRow() + i, range.leftColumn() + j, rows[i][j]);

17 }

18 clearSelection();

19 somethingChanged();

20 }

Сортировка работает на текущей выделенной области и переупорядочивает строки в соответствии со значениями ключей порядка сортировки, хранящимися в объекте compare. Мы представляем каждую строку данных в QStringList, а выделенную область храним в виде списка строк. Мы используем алгоритм Qt qStableSort() и для простоты сортируем по выражениям формул, а не по их значениям. Стандартные алгоритмы и структуры данных Qt рассматривается в («Классыконтейнеры»).

Рис. 4.8. Хранение выделенной области в виде списка строк.

В качестве аргументов функции qStableSort() используются итератор начала, итератор конца и функция сравнения. Функция сравнения имеет два аргумента (оба имеют тип QStringLists ), и она возвращает true, когда первый аргумент «больше, чем» второй аргумент, и false в противном случае. Передаваемый как функция сравнения объект compare фактически не является функцией, но он может использоваться и в таком качестве, в чем мы вскоре сможем убедиться.

Ваша оценка очень важна

0
Шрифт
Фон

Помогите Вашим друзьям узнать о библиотеке