На этом шаге продолжим рассматривать реализацию подкласса 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.
На следующем шаге рассмотрим синтаксический анализ формул в приложении Электронная таблица.