C++-GUI-Qt4-編程(第二版)-Chapter-4 實現(xiàn)應(yīng)用程序的功能_第1頁
C++-GUI-Qt4-編程(第二版)-Chapter-4 實現(xiàn)應(yīng)用程序的功能_第2頁
C++-GUI-Qt4-編程(第二版)-Chapter-4 實現(xiàn)應(yīng)用程序的功能_第3頁
C++-GUI-Qt4-編程(第二版)-Chapter-4 實現(xiàn)應(yīng)用程序的功能_第4頁
C++-GUI-Qt4-編程(第二版)-Chapter-4 實現(xiàn)應(yīng)用程序的功能_第5頁
已閱讀5頁,還剩36頁未讀, 繼續(xù)免費閱讀

付費下載

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

Chapter4實現(xiàn)應(yīng)用程序的功能4.1中央窗口部件QMainWindow的中央?yún)^(qū)域可以被任意種類的窗口部件所占用。下面給出的是對所有可能情形的概述。使用一個標(biāo)準(zhǔn)的Qt窗口部件使用一個自定義窗口部件使用一個帶布局管理器的普通QWidget使用切分窗口(splitter)使用多文檔界面工作空間4.2子類化QTableWidget類SpreadSheet派生自QTableWidget,如圖4.1所示。QTableWidget是一組格子,可以非常有效地用來表達(dá)二維稀疏數(shù)組。它可以在規(guī)定的維數(shù)內(nèi)顯示用戶滾動到的任一單元格。當(dāng)用戶在一個空單元格內(nèi)輸入一些文本的時候,QTableWidget會自動創(chuàng)建一個用來存儲這些文本的QTableWidgetItem。QTableWidget派生自QTableView,它是模型/視圖類之一。圖4.1類Spreadsheet和Cell的繼承樹讓我們一起來實現(xiàn)SpreadSheet,首先看他的頭文件。頭文件是從Cell和SpreadsheetCompare類的前置聲明開始的:#ifndefSPREADSHEET_H#defineSPREADSHEET_H#include<QTableWidget>classCell;classSpreadsheetCompare;之所以把a(bǔ)utoRecalculate()函數(shù)實現(xiàn)為內(nèi)聯(lián)函數(shù),是因為無論自動重新計算的標(biāo)識符生效與否,它都必須要有返回值。classSpreadsheet:publicQTableWidget{Q_OBJECTpublic:Spreadsheet(QWidget*parent=0);boolautoRecalculate()const{returnautoRecalc;}QStringcurrentLocation()const;QStringcurrentFormula()const;QTableWidgetSelectionRangeselectedRange()const;voidclear();boolreadFile(constQString&fileName);boolwriteFile(constQString&fileName);voidsort(constSpreadsheetCompare&compare);Spreadsheet提供了許多實現(xiàn)Edit、Tools和Options菜單中的動作的槽,并且它也提供了一個modified()信號,用來告知用戶可能已經(jīng)發(fā)生的任何變化。publicslots:voidcut();voidcopy();voidpaste();voiddel();voidselectCurrentRow();voidselectCurrentColumn();voidrecalculate();voidsetAutoRecalculate(boolrecalc);voidfindNext(constQString&str,Qt::CaseSensitivitycs);voidfindPrevious(constQString&str,Qt::CaseSensitivitycs);signals:voidmodified();還定義了一個有Spreadsheet內(nèi)部使用的私有槽:privateslots:voidsomethingChanged();在這個類的私有段中,聲明了3個常量、4個函數(shù)和一個變量。private:enum{MagicNumber=0x7F51C883,RowCount=999,ColumnCount=26};Cell*cell(introw,intcolumn)const;QStringtext(introw,intcolumn)const;QStringformula(introw,intcolumn)const;voidsetFormula(introw,intcolumn,constQString&formula);boolautoRecalc;};在這個頭文件的最后,給出了SpreadsheetCompare類的定義。classSpreadsheetCompare{public:booloperator()(constQStringList&row1,constQStringList&row2)const;enum{KeyCount=3};intkeys[KeyCount];boolascending[KeyCount];};#endif下面是它的實現(xiàn)文件:通常情況下,當(dāng)用戶在一個空單元格中輸入一些文本的時候,QTableWidget將會自動創(chuàng)建一個QTableWidgetItem來保存這些文本。同樣是在構(gòu)造函數(shù)中,我們將選擇模式設(shè)置為QAbstractItemView::ContiguousSelection,從而可以允許簡單矩形選擇框方法。#include<QtGui>#include"cell.h"#include"spreadsheet.h"Spreadsheet::Spreadsheet(QWidget*parent):QTableWidget(parent){autoRecalc=true;setItemPrototype(newCell);setSelectionMode(ContiguousSelection);connect(this,SIGNAL(itemChanged(QTableWidgetItem*)),this,SLOT(somethingChanged()));clear();}clear()函數(shù)是從Spreadsheet構(gòu)造函數(shù)中得到的調(diào)用的,用來初始化電子制作軟件。它也會在MainWindow::newFile()中得到調(diào)用。voidSpreadsheet::clear(){setRowCount(0);setColumnCount(0);setRowCount(RowCount);setColumnCount(ColumnCount);for(inti=0;i<ColumnCount;++i){QTableWidgetItem*item=newQTableWidgetItem;item->setText(QString(QChar('A'+i)));setHorizontalHeaderItem(i,item);}setCurrentCell(0,0);}QTableWidget由多個子窗口部件構(gòu)成。在它的頂部由一個水平的QHeaderView,左側(cè)有一個垂直的QHeaderView,還有兩個QScrollBar。在它的中間區(qū)域被一個名為視口(viewport)的特殊窗口部件所占用,QTableWidget可以在它上面繪制單元格。通過QTableView和QAbstractScrollArea中繼承的一些函數(shù),可以訪問這些不同的子窗口部件(參見圖4.2)。圖4.2構(gòu)成QTableWidget的各個窗口部件cell()私有函數(shù)可以根據(jù)給定的行和列返回一個Cell對象。Cell*Spreadsheet::cell(introw,intcolumn)const{returnstatic_cast<Cell*>(item(row,column));}text()私有函數(shù)可以返回給定單元格中的文本。QStringSpreadsheet::text(introw,intcolumn)const{Cell*c=cell(row,column);if(c){returnc->text();}else{return"";}}formula()函數(shù)返回給定單元格中的公式。QStringSpreadsheet::formula(introw,intcolumn)const{Cell*c=cell(row,column);if(c){returnc->formula();}else{return"";}}currentLocation()函數(shù)返回當(dāng)前單元格的位置,它是按照電子制表軟件的通常格式,也就是一個列字母跟上行號的形式來表示這個位置的值。setFormula()私有函數(shù)可以設(shè)置用于給定單元格的公式。voidSpreadsheet::setFormula(introw,intcolumn,constQString&formula){Cell*c=cell(row,column);if(!c){c=newCell;setItem(row,column,c);}c->setFormula(formula);}QStringSpreadsheet::currentLocation()const{returnQChar('A'+currentColumn())+QString::number(currentRow()+1);}currentFormula()函數(shù)返回當(dāng)前單元格的公式。QStringSpreadsheet::currentFormula()const{returnformula(currentRow(),currentColumn());}如果啟用了“auto-recalculate”(自動重新計算),那么somethingChanged()私有槽就會重新計算整個電子制表軟件。它也會發(fā)射modified()信號。voidSpreadsheet::somethingChanged(){if(autoRecalc)recalculate();emitmodified();}4.3載入和保存現(xiàn)在,我們將使用一種自定義的二進(jìn)制數(shù)格式來實現(xiàn)Spreadsheet文件的載入和保存。將使用QFile和QDataStream來完成這一工作,由它們共同提供與平臺無關(guān)的二進(jìn)制數(shù)輸入/輸出借口。首先從一個Spreadsheet文件的輸出開始:boolSpreadsheet::writeFile(constQString&fileName){QFilefile(fileName);if(!file.open(QIODevice::WriteOnly)){QMessageBox::warning(this,tr("Spreadsheet"),tr("Cannotwritefile%1:\n%2.").arg(file.fileName()).arg(file.errorString()));returnfalse;}QDataStreamout(&file);out.setVersion(QDataStream::Qt_4_3);out<<quint32(MagicNumber);QApplication::setOverrideCursor(Qt::WaitCursor);

for(introw=0;row<RowCount;++row){for(intcolumn=0;column<ColumnCount;++column){QStringstr=formula(row,column);if(!str.isEmpty())out<<quint16(row)<<quint16(column)<<str;}}QApplication::restoreOverrideCursor();returntrue;}從MainWindow::saveFile()中調(diào)用的writeFile()函數(shù)把文件輸出到磁盤中。我們使用給定的文件名創(chuàng)建一個QFile對象,并且調(diào)用open()打開這個用于輸出的文件。我們也會創(chuàng)建一個QDataStream對象,由它操作這個QFile對象并且使用該對象輸出數(shù)據(jù)。

QDataStream既可以支持C++基本類型,也可以支持多種Qt類型。該語法模仿了標(biāo)準(zhǔn)C++的<iostream>中的那些類的語法。Spreadsheet應(yīng)用程序的文件格式是相當(dāng)簡單的。一個Spreadsheet文件以一個32位數(shù)字作為文件的開始,由它確定文件的格式。然后是連續(xù)的數(shù)據(jù)塊,每一數(shù)據(jù)塊都包含了用于一個單元格中的行、列和公式。為了節(jié)省空間,我們沒有輸出空白單元格。該文件格式如圖4.3所示:圖4.3Spreadsheet的文件格式關(guān)于這些數(shù)據(jù)類型的二進(jìn)制數(shù)確切表示方法則是由QDataStream決定的。QDataStream的功能非常齊全。既可以把它用于QFile中,也可以用于QBuffer、QProcess、QTcpSocket、QUdpSocket或者QSslSocket中。在讀取和輸出文本文件時,Qt也提供了一個QTextStream類,可以使用它來代替QDataStream類。readFile()函數(shù)與writeFile()函數(shù)非常相似。boolSpreadsheet::readFile(constQString&fileName){QFilefile(fileName);if(!file.open(QIODevice::ReadOnly)){QMessageBox::warning(this,tr("Spreadsheet"),tr("Cannotreadfile%1:\n%2.").arg(file.fileName()).arg(file.errorString()));returnfalse;}QDataStreamin(&file);in.setVersion(QDataStream::Qt_4_3);quint32magic;in>>magic;if(magic!=MagicNumber){QMessageBox::warning(this,tr("Spreadsheet"),tr("ThefileisnotaSpreadsheetfile."));returnfalse;}clear();quint16row;quint16column;QStringstr;

QApplication::setOverrideCursor(Qt::WaitCursor);while(!in.atEnd()){in>>row>>column>>str;setFormula(row,column,str);}QApplication::restoreOverrideCursor();returntrue;}我們使用QFile讀取一個文件,但這一次使用的是QIODevice::ReadOnly標(biāo)記,而不是QIODevice::WriteOnly標(biāo)記。然后,把QDataStream的版本設(shè)置為9。用于讀取文件的格式必須總是與輸出文件的格式相同。如果該文件在開始處具有正確的幻數(shù)(magicnumber),那么可以調(diào)用clear()來清空電子制表軟件中的所有單元格,并且讀入單元格中的數(shù)據(jù)。由于該文件中只包含那些非空單元格的數(shù)據(jù),并且也不大可能重置電子制表軟件中的每個單元格,所以必須確保在讀入數(shù)據(jù)之氣那已經(jīng)清空了所有的單元格。4.4實現(xiàn)Edit菜單

Spreadsheet應(yīng)用程序中的Edit菜單如圖4.4所示。圖4.4Spreadsheet應(yīng)用程序的Edit菜單cut槽可以對Edit->Cut菜單做出響應(yīng)。voidSpreadsheet::cut(){copy();del();}copy()槽能偶對Edit->Copy做出響應(yīng)。它會遍歷當(dāng)前選擇。每一個選中單元格的公式都會被添加到一個QString中,行與行之間利用換行符“\n”分隔,列與列之間則以制表符“\t”來分隔。圖4.5給出了這一實現(xiàn)方法的示意圖。voidSpreadsheet::copy(){QTableWidgetSelectionRangerange=selectedRange();QStringstr;for(inti=0;i<range.rowCount();++i){if(i>0)str+="\n";for(intj=0;j<range.columnCount();++j){if(j>0)str+="\t";str+=formula(range.topRow()+i,range.leftColumn()+j);}}QApplication::clipboard()->setText(str);}圖4.5把選擇復(fù)制到剪貼板中函數(shù)QTableWidget::selectRanges()返回一個選擇范圍列表。QTableWidgetSelectionRangeSpreadsheet::selectedRange()const{QList<QTableWidgetSelectionRange>ranges=selectedRanges();if(ranges.isEmpty())returnQTableWidgetSelectionRange();returnranges.first();}如果只有一個選擇,則只需簡單地返回第一個(并且也只有這一個)選擇即可。沒有選擇的情況應(yīng)該永遠(yuǎn)不會發(fā)生,因為ContiguousSelection模式至少可以把當(dāng)前單元格當(dāng)作是已經(jīng)選中的選擇。但是,為了避免使程序出現(xiàn)缺陷的可能,還是需要對這種當(dāng)前沒有選中單元格的情況進(jìn)行單獨處理。paste()槽對Edit->Paste()菜單選項做出響應(yīng)。voidSpreadsheet::paste(){QTableWidgetSelectionRangerange=selectedRange();QStringstr=QApplication::clipboard()->text();QStringListrows=str.split('\n');intnumRows=rows.count();intnumColumns=rows.first().count('\t')+1;if(range.rowCount()*range.columnCount()!=1&&(range.rowCount()!=numRows||range.columnCount()!=numColumns)){QMessageBox::information(this,tr("Spreadsheet"),tr("Theinformationcannotbepastedbecausethecopy""andpasteareasaren'tthesamesize."));return;}for(inti=0;i<numRows;++i){QStringListcolumns=rows[i].split('\t');for(intj=0;j<numColumns;++j){introw=range.topRow()+i;intcolumn=range.leftColumn()+j;if(row<RowCount&&column<ColumnCount)setFormula(row,column,columns[j]);}}somethingChanged();}為了執(zhí)行粘貼操作,我們遍歷所有行并且再次使用QString::split()把它們分隔到每一個單元格中,但是這次以要把制表符“\t”當(dāng)作分隔符。圖4.6給出了這以過程中所使用的步驟。圖4.6把剪貼板中的文本粘貼到電子制表軟件中del()槽對Edit->Delete菜單選項做出響應(yīng)。如果有選中的項,那么就會刪除它們并且調(diào)用somethingChanged()函數(shù)。對選擇中的每一個Cell對象使用delete足以清空所有這些單元格。voidSpreadsheet::del(){QList<QTableWidgetItem*>items=selectedItems();if(!items.isEmpty()){foreach(QTableWidgetItem*item,items)deleteitem;somethingChanged();}}selectCurrentRow()和selectCurrentColumn()對Edit->Select->Row和Edit->Select->Column菜單選項做出響應(yīng)。這些實現(xiàn)分別依賴于QTableWidget的selectRow()和selectColumn()函數(shù)。voidSpreadsheet::selectCurrentRow(){selectRow(currentRow());}voidSpreadsheet::selectCurrentColumn(){selectColumn(currentColumn());}findNext()槽會遍歷單元格一遍,它從當(dāng)前光標(biāo)右側(cè)的單元格開始遍歷到這一行的最后一列,然后再從下一行的第一個單元格開始繼續(xù)遍歷,如此反復(fù),直到找到所要查找的文本,或者是直到最后一個單元格為止。voidSpreadsheet::findNext(constQString&str,Qt::CaseSensitivitycs){introw=currentRow();intcolumn=currentColumn()+1;while(row<RowCount){while(column<ColumnCount){if(text(row,column).contains(str,cs)){clearSelection();setCurrentCell(row,column);activateWindow();return;}++column;}column=0;++row;}QApplication::beep();}findPrevious()槽與findNext()槽相似,區(qū)別之處是它會向相反的方向遍歷并且會在單元格A1處停下來。voidSpreadsheet::findPrevious(constQString&str,Qt::CaseSensitivitycs){introw=currentRow();intcolumn=currentColumn()-1;while(row>=0){while(column>=0){if(text(row,column).contains(str,cs)){clearSelection();setCurrentCell(row,column);activateWindow();return;}--column;}column=ColumnCount-1;--row;}QApplication::beep();}4.5實現(xiàn)其他菜單 現(xiàn)在我們將要實現(xiàn)那些對Tools和Options菜單做出響應(yīng)的槽。這些菜單項如圖4.7所示。圖4.7Spreadsheet應(yīng)用程序的Tools和Optionsrecalculate()槽能夠?qū)ools->Recalculate菜單項做出響應(yīng)。當(dāng)必要時,它也會被Spreadsheet自動調(diào)用。voidSpreadsheet::recalculate(){for(introw=0;row<RowCount;++row){for(intcolumn=0;column<ColumnCount;++column){if(cell(row,column))cell(row,column)->setDirty();}}viewport()->update();}setAutoRecalculate()槽對Options->Auto-Recalculate菜單選項做出響應(yīng)。如果啟動了這個特性,則會立即重新計算整個電子制表軟件以確保它是最新的,然后,recalculate()會自動在somethingChanged()得到調(diào)用。voidSpreadsheet::setAutoRecalculate(boolrecalc){autoRecalc=recalc;if(autoRecalc)recalculate();}因為QTableWidget已經(jīng)提供了一個從QTableView中繼承而來的setShowGrid()槽,所以不需要再對Options->ShowGrid菜單選項編寫任何代碼。所有要保留的東西就是Spreadsheet::sort(),它會在MainWindow::sort()中得到調(diào)用:voidSpreadsheet::sort(constSpreadsheetCompare&compare){QList<QStringList>rows;QTableWidgetSelectionRangerange=selectedRange();inti;for(i=0;i<range.rowCount();++i){QStringListrow;for(intj=0;j<range.columnCount();++j)row.append(formula(range.topRow()+i,range.leftColumn()+j));rows.append(row);}

qStableSort(rows.begin(),rows.end(),compare);for(i=0;i<range.rowCount();++i){for(intj=0;j<range.columnCount();++j)setFormula(range.topRow()+i,range.leftColumn()+j,rows[i][j]);}clearSelection();somethingChanged();}排序操作會對當(dāng)前的選擇進(jìn)行,并且會根據(jù)存儲在compare對象中的排序鍵和排序順序重新排列這些。我們使用一個QStringList來重新表示每一行數(shù)據(jù),并且把該選擇存儲在一個行列表中。我們使用Qt的qStableSort()算法,并且根據(jù)公式而不是根據(jù)值來進(jìn)行簡單排序。這一過程如圖4.8和圖4.9所示。圖4.8把選擇存儲為一個行列表圖4.9排序后把數(shù)據(jù)放回表中在spreadsheet.h文件中,SpreadsheetCompare類的定義如下。SpreadsheetCompare類有些特殊,因為它實現(xiàn)了一個“()”操作符,這樣就允許把這個類像函數(shù)一樣使用。classSpreadsheetCompare{public:booloperator()(constQStringList&row1,constQStringList&row2)const;enum{KeyCount=3};intkeys[KeyCount];boolascending[KeyCount];};Square類提供了一個函數(shù),operator()(int)函數(shù),它返回其參數(shù)的平方值。classSquare{public:intoperator()(intx)const{returnx*x;}}現(xiàn)在讓我們來看一個包括SpreadsheetCompare的實例:QStringListrow1,row2;SpreadsheetComparecompare;...if(compare(row1,row2)){//row1islessthanrow2}這里給出的是對電子制表軟件中的兩個行進(jìn)行比較的函數(shù)實現(xiàn):boolSpreadsheetCompare::operator()(constQStringList&row1,constQStringList&row2)const{for(inti=0;i<KeyCount;++i){intcolumn=keys[i];if(column!=-1){if(row1[column]!=row2[column]){if(ascending[i]){returnrow1[column]<row2[column];}else{returnrow1[column]>row2[column];}}}}returnfalse;}4.6子類化QTableWidgetItem

Cell類派生自QTableWidgetItem類。這個類被設(shè)計用于和Spreadsheet一起工作,但是它對類QTableWidgetItem沒有任何特殊依賴關(guān)系,所以在理論上講,它也可以用于任意的QTableWidget類中。這里給出的是Cell類的頭文件:#ifndefCELL_H#defineCELL_H#include<QTableWidgetItem>classCell:publicQTableWidgetItem{public:Cell();QTableWidgetItem*clone()const;voidsetData(introle,constQVariant&value);QVariantdata(introle)const;voidsetFormula(constQString&formula);QStringformula()const;voidsetDirty();private:QVariantvalue()const;QVariantevalExpression(constQString&str,int&pos)const;QVariantevalTerm(constQString&str,int&pos)const;QVariantevalFactor(constQString&str,int&pos)const;mutableQVariantcachedValue;mutableboolcacheIsDirty;};#endif通過增加兩個私有變量,Cell類對QTableWidgetItem進(jìn)行了擴(kuò)展:

cacheValue把單元格的值緩存為QVariant。如果緩存的值不是最新的,那么就把cacheIsDirty設(shè)置為trut。以下是cell.cpp文件的開始部分。在構(gòu)造函數(shù)中,只需要將緩存設(shè)置為dirty。#include<QtGui>#include"cell.h"Cell::Cell(){setDirty();}當(dāng)QTableWidget需要創(chuàng)建一個新的單元格時,例如,當(dāng)用戶在一個以前沒有使用過的空白單元格中開始輸入數(shù)據(jù)時,它就會調(diào)用clone()函數(shù)。QTableWidgetItem*Cell::clone()const{returnnewCell(*this);}setFormula()函數(shù)用來設(shè)置單元格中的公式。它只是一個對編輯角色調(diào)用setData()的簡便函數(shù)。也可以從Spreadsheet::setFormula()調(diào)用它。voidCell::setFormula(constQString&formula){setData(Qt::EditRole,formula);}foemula()函數(shù)會從Spreadsheet::formula()中得到調(diào)用。就像setFormula()函數(shù)一樣,它也是一個簡便函數(shù),這次是重新獲得該項的EditRole數(shù)據(jù)。QStringCell::formula()const{returndata(Qt::EditRole).toString();}如果有一個新的公式,就可以把cacheIsDirty設(shè)置為true,以確保在下一次調(diào)用text()的時候可以重新計算該單元格。voidCell::setData(introle,constQVariant&value){QTableWidgetItem::setData(role,value);if(role==Qt::EditRole)setDirty();}調(diào)用setDirty()函數(shù)可以用來對該單元格的值強(qiáng)制進(jìn)行重新計算。voidCell::setDirty(){cacheIsDirty=true;}data()函數(shù)是從QTableWidgetItem中重新實現(xiàn)的。如果使用Qt::DisplayRole調(diào)用這個函數(shù),那么它返回在電子制表軟件中應(yīng)該顯示的文本;如果使用Qt::EditRole調(diào)用這個函數(shù),那么它返回該單元格中的公式;如果使用Qt::TextAlignmentRole調(diào)用這個函數(shù),那么它返回一個合適的對齊方式。QVariantCell::data(introle)const{if(role==Qt::DisplayRole){if(value().isValid()){returnvalue().toString();}else{return"####";}}elseif(role==Qt::TextAlignmentRole){if(value().type()==QVariant::String){returnint(Qt::AlignLeft|Qt::AlignVCenter);}else{returnint(Qt::AlignRight|Qt::AlignVCenter);}}else{returnQTableWidgetItem::data(role);}}constQVariantInvalid;QVariantCell::value()const{if(cacheIsDirty){cacheIsDirty=false;QStringformulaStr=formula();if(formulaStr.startsWith('\'')){cachedValue=formulaStr.mid(1);}elseif(formulaStr.startsWith('=')){cachedValue=Invalid;QStringexpr=formulaStr.mid(1);expr.replace("","");expr.append(QChar::Null);intpos=0;cachedValue=evalExpression(expr,pos);if(expr[pos]!=QChar::Null)cachedValue=Invalid;}else{boolok;doubled=formulaStr.toDouble(&ok);if(ok){cachedValue=d;}else{cachedValue=formulaStr;}}}returncachedValue;}value()私有函數(shù)返回這個單元格的值。在圖4.10中,定義了電子制表軟件表達(dá)式的語法。對于語法中的每一個符號,都對應(yīng)一個解析它的成員函數(shù),并且函數(shù)的結(jié)構(gòu)嚴(yán)格遵循語法。通過這種方式寫出的解析器稱為遞歸漸降解析器。圖4.10用于電子制表軟件表達(dá)式中的語法圖如果公式是由單引號開始的,那么這個單引號就會占用位置0,而值就是從位置1到最后位置的一個字符串。如果公式是由等號開始的,那么會使用從位置1開始的字符串,并且將它可能包含的任意空格全部移除。如果公式不是由單引號或者等號開始的,那么可以使用toDouble()試著把它轉(zhuǎn)換為浮點數(shù)。讓我們先從evalExpression()開始,這個函數(shù)可以解析一個表達(dá)式。QVariantCell::evalExpression(constQString&str,int&pos)const{QVariantresult=evalTerm(str,pos);while(str[pos]!=QChar::Null){QCharop=str[pos];if(op!='+'&&op!='-')returnresult;++pos;

QVariantterm=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;}}returnresult;}除了evaTerm()函數(shù)是處理乘法和除法這一點不同之外,它和evalExpression()都很相似。Q

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論