Слияние кода завершено, страница обновится автоматически
#include "cell.h"
/*
* setdata()将数据放入“单元格” 输入
* data() 从“单元格”中取出数据 显示
*
* 每个QTableWidgetItem都可以保存一些数据,最多可以为每一个数据角色分配一个QVariant变量
* Qt::DisplayRole 用于需要显示的数据上,单元格的值(对公式求值后的结果)
* Qt::EditRole 用于需要编辑的角色, 单元格公式
*
* ???单元格中一切皆字符串,在QT中就用QString类型, 然后根据你单元格中的内容进行转换,
*/
Cell::Cell()
{
setDirty();
}
QTableWidgetItem *Cell::clone() const
{
return new Cell(*this);
}
QVariant Cell::data(int role) const
{
if(role==Qt::DisplayRole)
{
if(value().isValid())
{
return value().toString();
}else{
return "####";
}
}else if(role==Qt::TextAlignmentRole){
if(value().type()==QVariant::String)
{
return int(Qt::AlignLeft|Qt::AlignVCenter);
}else{
return int(Qt::AlignRight|Qt::AlignCenter);
}
}else{
return QTableWidgetItem::data(role);
}
}
const QVariant Invalid;
QVariant Cell::value()const
{
if(cacheIsDirty)
{
QString formulaStr=formula(); //所有的输入都当作“公式”
if(formulaStr.startsWith('\''))
{
cacheValue=formulaStr.mid(1);
}else if(formulaStr.startsWith('=')){
cacheValue=Invalid;
QString expr=formulaStr.mid(1);
expr.replace("","");
expr.append(QChar::Null);
int pos=0;
cacheValue=evalExpression(expr,pos);
if(expr[pos]!=QChar::Null)
cacheValue=Invalid;
}else{
bool ok;
double d=formulaStr.toDouble(&ok);
if(ok)
{
cacheValue=d;
}else{
cacheValue=formulaStr;
}
}
cacheIsDirty=false;
}
return cacheValue;
}
QString Cell::formula()const
{
return data(Qt::EditRole).toString();
}
void Cell::setFormula(const QString &formula)
{
setData(Qt::EditRole,formula);
}
void Cell::setData(int role, const QVariant &value)
{
QTableWidgetItem::setData(role,value);
if(role==Qt::EditRole)
setDirty();
}
void Cell::setDirty()
{
cacheIsDirty=true;
}
QVariant Cell::evalExpression(const QString &str, int &pos) const
{
QVariant result = evalTerm(str, pos);
while (str[pos] != QChar::Null) {
QChar op = str[pos];
if (op != '+' && op != '-')
return result;
++pos;
QVariant term = evalTerm(str, pos);
if (result.type() == QVariant::Double
&& term.type() == QVariant::Double) {
if (op == '+') {
result = result.toDouble() + term.toDouble();
} else {
result = result.toDouble() - term.toDouble();
}
} else {
result = Invalid;
}
}
return result;
}
QVariant Cell::evalTerm(const QString &str, int &pos) const
{
QVariant result = evalFactor(str, pos);
while (str[pos] != QChar::Null) {
QChar op = str[pos];
if (op != '*' && op != '/')
return result;
++pos;
QVariant factor = evalFactor(str, pos);
if (result.type() == QVariant::Double
&& factor.type() == QVariant::Double) {
if (op == '*') {
result = result.toDouble() * factor.toDouble();
} else {
if (factor.toDouble() == 0.0) {
result = Invalid;
} else {
result = result.toDouble() / factor.toDouble();
}
}
} else {
result = Invalid;
}
}
return result;
}
QVariant Cell::evalFactor(const QString &str, int &pos) const
{
QVariant result;
bool negative = false;
if (str[pos] == '-') {
negative = true;
++pos;
}
if (str[pos] == '(') {
++pos;
result = evalExpression(str, pos);
if (str[pos] != ')')
result = Invalid;
++pos;
} else {
QRegExp regExp("[A-Za-z][1-9][0-9]{0,2}");
QString token;
while (str[pos].isLetterOrNumber() || str[pos] == '.') {
token += str[pos];
++pos;
}
if (regExp.exactMatch(token)) {
int column = token[0].toUpper().unicode() - 'A';
int row = token.mid(1).toInt() - 1;
Cell *c = static_cast<Cell *>(
tableWidget()->item(row, column));
if (c) {
result = c->value();
} else {
result = 0.0;
}
} else {
bool ok;
result = token.toDouble(&ok);
if (!ok)
result = Invalid;
}
}
if (negative) {
if (result.type() == QVariant::Double) {
result = -result.toDouble();
} else {
result = Invalid;
}
}
return result;
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )