На этом шаге продолжим рассматривать реализацию подкласса QTableWidgetItem.
Закрытая функция value() возвращает значение ячейки.
const QVariant Invalid;
QVariant Cell::value() const
{
/*Если флажок cachelsDirty имеет значение true, нам необходимо
выполнить перерасчет значения*/
if (cacheIsDirty) {
cacheIsDirty = false;
QString formulaStr = formula();
/*Если формула начинается с одиночной кавычки (например, "'12345"),
то одиночная кавычка занимает позицию 0, а значение представляет собой
строку в позициях с 1 до последней*/
if (formulaStr.startsWith('\'')) {
cachedValue = formulaStr.mid(1);
}
/*Если формула начинается со знака равенства ("="),
мы выделяем строку, начиная с позиции 1, и удаляем из нее любые пробелы.
Затем мы вызываем функцию evalExpression() для вычисления значения
выражения. Аргумент pos передается по ссылке; он задает позицию символа,
с которого должен начинаться синтаксический анализ выражения. После
вызова функции evalExpression() в позиции pos нами должен быть установлен
символ QChar::Null, если синтаксический анализ завершился успешно. Если
синтаксический анализ не закончился успешно, мы устанавливаем cachedValue
на значение Invalid*/
else if (formulaStr.startsWith('=')) {
cachedValue = Invalid;
QString expr = formulaStr.mid(1);
expr.replace(" ", "");
expr.append(QChar::Null);
int pos = 0;
cachedValue = evalExpression(expr, pos);
if (expr[pos] != QChar::Null)
cachedValue = Invalid;
}
/*Если формула не начинается с одиночной кавычки или знака равенства,
мы пытаемся преобразовать ее в число с плавающей точкой, используя
функцию toDouble(). Если преобразование удается выполнить, мы
устанавливаем cachedValue на полученное значение; в противном случае
устанавливаем cachedValue на строку формулы. Например, формула "1.50"
приводит к тому, что функция toDouble() устанавливает переменную ok на
значение true и возвращает 1.5, а формула "население Земли"
приводит к тому, что функция toDouble()устанавливает переменную ok на
значение false и возвращает 0.0. Благодаря заданному в функции toDouble()
указателю на булево значение мы можем отличать строку преобразования,
представляющую числовое значение 0.0, от ошибки преобразования (в
последнем случае также возвращается 0.0, но булева переменная
устанавливается в значение false). Иногда нулевое значение при неудачном
преобразовании оказывается именно тем, что нам нужно; в этом случае нет
необходимости передавать указать на переменную типа bool. По причинам,
связанным с производительностью и переносимостью, в Qt никогда не
используются исключения C++ для вывода сообщений об ошибках. Это не
значит, что вы не можете использовать их в своих Qt-программах, если ваш
компилятор поддерживает исключения C++*/
else {
bool ok;
double d = formulaStr.toDouble(&ok);
if (ok) {
cachedValue = d;
} else {
cachedValue = formulaStr;
}
}
}
return cachedValue;
}Функция value() объявлена с модификатором const. При объявлении переменных cachedValue и cachelsValid мы использовали ключевое слово mutable, чтобы компилятор позволял нам модифицировать эти переменные в функциях типа const. Может показаться заманчивой возможность сделать функцию value() не типа const и удалить ключевые слова mutable, но это не пропустит компилятор, поскольку мы вызываем value() из data(), функции с модификатором const.
На следующем шаге рассмотрим синтаксический анализ формул в приложении Электронная таблица.