關(guān)于Subclassing QTableWidget中QTableWidget繼承
對于Qt 類前面已經(jīng)介紹的很詳細了,在本篇文章中就不多介紹了。那么本文講述的內(nèi)容是關(guān)于Subclassing QTableWidget中QTableWidget繼承。QTableWidget是一個表示二維離散數(shù)組的表格。它在給定維度里顯示當前用戶滾動的單元格。當用戶在一個空的單元格中輸入一些文本時,QTableWidget自動創(chuàng)建一個QTableWidgetItem對象保存輸入的文本。
現(xiàn)在我們來實現(xiàn)這個類,首先是頭文件spreadsheet.h,首先前向聲明兩個類Cell和SpreadsheetCompare。
- #ifndef SPREADSHEET_H
- #define SPREADSHEET_H
- #include <QTableWidget>
- class Cell;
- class SpreadsheetCompare;
- class Spreadsheet : public QTableWidget{
- Q_OBJECTpublic:
- Spreadsheet(QWidget *parent = 0);
- bool autoRecalculate() const { return autoRecalc; }//內(nèi)聯(lián)函數(shù)
- QString currentLocation() const;
- QString currentFormula() const;
- QTableWidgetSelectionRange selectedRange() const;
- void clear();
- bool readFile(const QString &fileName);
- bool writeFile(const QString &fileName);
- void sort(const SpreadsheetCompare &compare);
- public slots:
- void cut();
- void copy();
- void paste();
- void del();
- void selectCurrentRow();
- void selectCurrentColumn();
- void recalculate();
- void setAutoRecalculate(bool recalc);
- void findNext(const QString &str, Qt::CaseSensitivity cs);
- void findPrevious(const QString &str, Qt::CaseSensitivity cs);signals:
- void modified();private slots:
- void somethingChanged();
- private:
- enum { MagicNumber = 0x7F51C883, RowCount = 999, ColumnCount = 26 };
- Cell *cell(int row, int column) const;
- QString text(int row, int column) const;
- QString formula(int row, int column) const;
- void setFormula(int row, int column, const QString &formula);
- bool autoRecalc;};class SpreadsheetCompare{public:
- bool operator()(const QStringList &row1,
- const QStringList &row2) const;
- enum { KeyCount = 3 };
- int keys[KeyCount];
- bool ascending[KeyCount];
- };
- #endif
文本,對齊等這個QTableWidget單元格的屬性存儲在QTableWidgetItem類里。QTableWidgetItem類不是一個控件類,而是一個單純保存數(shù)據(jù)的類。
實現(xiàn)MainWindow類的時候我們用到了Spreadsheet的一些公有函數(shù)。如在MainWindow::newFile中調(diào)用clear()將表格置空。我們也用到了QTableWidget繼承來的一些函數(shù),如setCurrentCell()和setShowGrid()就多次調(diào)用過。
#p#
Spreadsheet提供了很多槽函數(shù)來相應(yīng)Edit,Tools和Options等菜單的動作。信號modified()在表格發(fā)生變化時給出通知。私有槽函數(shù)somethingChanged()在Speadsheet類內(nèi)部使用。
在類的私有部分,我們聲明了三個常數(shù),四個函數(shù)和一個變量。在頭文件的最后定義了類SpreadsheetCompare
現(xiàn)在我們看一下源文件 spreadsheet.cpp:
- #include <QtGui>
- #include "cell.h"
- #include "spreadsheet.h"
- Spreadsheet::Spreadsheet(QWidget *parent)
- : QTableWidget(parent)
- {
- autoRecalc = true;
- setItemPrototype(new Cell);
- setSelectionMode(ContiguousSelection);
- connect(this, SIGNAL(itemChanged(QTableWidgetItem *)),
- this, SLOT(somethingChanged()));
- clear();
- }
- void Spreadsheet::clear()
- {
- setRowCount(0);
- setColumnCount(0);
- setRowCount(RowCount);
- setColumnCount(ColumnCount);
- for (int i = 0; i < ColumnCount; ++i) {
- QTableWidgetItem *item = new QTableWidgetItem;
- item->setText(QString(QChar('A' + i)));
- setHorizontalHeaderItem(i, item);
- }
- setCurrentCell(0, 0);
- }
- Cell *Spreadsheet::cell(int row, int column) const
- {
- return static_cast<Cell *>(item(row, column));
- }
- QString Spreadsheet::text(int row, int column) const
- {
- Cell *c = cell(row, column);
- if (c) {
- return c->text();
- } else {
- return "";
- }
- }
- QString Spreadsheet::formula(int row, int column) const
- {
- Cell *c = cell(row, column);
- if (c) {
- return c->formula();
- } else {
- return "";
- }
- }
- void Spreadsheet::setFormula(int row, int column,
- const QString &formula)
- {
- Cell *c = cell(row, column);
- if (!c) {
- c = new Cell;
- setItem(row, column, c);
- }
- c->setFormula(formula);
- }
- QString Spreadsheet::currentLocation() const
- {
- return QChar('A' + currentColumn())
- + QString::number(currentRow() + 1);
- }
- QString Spreadsheet::currentFormula() const
- {
- return formula(currentRow(), currentColumn());
- }
- void Spreadsheet::somethingChanged()
- {
- if (autoRecalc)
- recalculate();
- emit modified();
- }
通常,用戶在一個空的單元格中輸入文本時,QTableWidget將會自動創(chuàng)建 QTableWidgetItem對象來保存這些文本。然而在 spreadsheet程序中,我們通過創(chuàng)建Cell 代替QTableWidgetItem。在構(gòu)造函數(shù)中,通過調(diào)用setItemProtoType()來實現(xiàn)。實際上是每次當需要創(chuàng)建一個新的項目時,QTableWidget 拷貝傳遞給setItemProtoType() 函數(shù)中的項目。
#p#
在構(gòu)造函數(shù)中,我們設(shè)置選擇方式QAbstractItemView::ContiguousSelection允許單一的矩形選擇。連接表格控件的信號itemChanged()和私有的somethingChanged()槽函數(shù),這樣當用戶編輯了一個單元格時,somethingChanged()能夠被調(diào)用。最后,我們調(diào)用clear()清空表格,設(shè)置列標頭。
在構(gòu)造函數(shù)中調(diào)用 clear()用來初始化表格。在MainWindow::newFile() 中也調(diào)用了這個函數(shù)。本來可以使用函數(shù)QTableWidget::clear()清除所有項和選擇,但這樣不能改變當前大小的標題頭。因此我們首先把表格重新定義為 0×0,這樣全部清除了表格和標題頭。然后把表格重新定義為ColumnCount×RowCount(26× 999),讓水平標題頭為QTableWidgetItem 類型,文本為"A"到"Z "。垂直標題欄會自動設(shè)置為1,2,到999。最后把光標移動到 A1。
QTableWidget由幾個子控件組成。它在最上面有一個水平的QHeaderView,最左邊有一個垂直的QHeaderView和兩個QScrollBars。中間區(qū)域是一個特殊的viewport控件,這個控件可以顯示網(wǎng)格。這些子控件可以通過QTableView和QAbstractScrollArea的函數(shù)進行操作。QAbstractScrollArea提供了一個可以滾動的viewport和兩個滾動條。它的子類是 QScrollArea。
在 Items中保存數(shù)據(jù):
在 Spreadsheet應(yīng)用程序中,每一個非空的單元格都作為一個獨立的 QTableWidgetItem對象被存放在內(nèi)存中。這種在 Item中保存數(shù)據(jù)的方法被QListWidget 和QTreeWidget所采用,對應(yīng)這兩個控件的Item類分別為QListWidgetItem和QTreeWidgetItem。
Qt的Item類還可以作為數(shù)據(jù)存儲器使用。比如,QTableWidgetItem也保存了一些屬性如文本,字體,顏色,圖標等,還有一個指向QTableWidget的指針。這個Item還可以保存QVariant類型的數(shù)據(jù),包括注冊的自定義類型。從這個類派生子類,我們還可以提供其他功能。
其他的工具是在它們的 item類中提供一個空指針來保存用戶數(shù)據(jù)。在 Qt中更加好用的方法是使用setData() ,把QVariant類型的數(shù)據(jù)保存起來。如果需要一個空類型指針,也可以從item類派生,在派生類中添加一個空類型指針成員變量。
對于那些更為復(fù)雜的數(shù)據(jù)處理,如大量的數(shù)據(jù),復(fù)雜的數(shù)據(jù)項,數(shù)據(jù)庫數(shù)據(jù)和多種數(shù)據(jù)顯示方式,Qt提供了一套model/view類將數(shù)據(jù)和顯示分離出來,第十章介紹了這個特性。
私有函數(shù) cell()返回指定的行數(shù)和列數(shù)的Cell對象。它和QTableWidget::item()是一樣的,只是它返回的是Cell類型的指針,QTableWidget::item()返回的是QTableWidgetItem類型的指針。
私有函數(shù) text()返回指定的單元格的文本。如果cell() 返回空指針,該單元格為空,則返回空字符。
函數(shù) formula()返回的是單元格的公式。大多數(shù)情況下,單元格的公式和文本是一樣的。例如,公式" hello"和字符"hello"是一樣的,如果用戶輸入了"hello",網(wǎng)格的文本就顯示為hello。但是下面會是例外:
1、如果公式是一個數(shù)字,那么單元格的文本也是數(shù)字。
2、如果公式是單引號開頭,公式的其他部分就是文本。如公式'12345,等價于串就是"12345" 。
3、如果公式由等號"="開頭,代表一個數(shù)學公式。如果A1為12, A2為6,那么公式"=A1+A2 "就是18。
把公式轉(zhuǎn)換為值的任務(wù)是由類 Cell完成的。此時需要記住的是單元格中顯示的文本是經(jīng)過公式計算的結(jié)果,而不是公式本身。
私有函數(shù) setFormula()用來給一個指定的單元格設(shè)置公式。如果該單元格有 Cell對象,那就使用這個對象。否則,我們創(chuàng)建一個新的 Cell對象,然后我們調(diào)用QTableWidget::setItem() 函數(shù)把它插入到表格中,最后調(diào)用單元格自己的setFormula()函數(shù),在單元格上顯示公式結(jié)果。我們不用刪除Cell對象,在適當?shù)臅r候,QTableWidget會自動刪除這些對象。
函數(shù) currentLocation()返回當前單元格的位置,字母顯示的列和行號,被 MainWindow::updateStatusBar()調(diào)用在狀態(tài)條上顯示位置。
函數(shù) currentFormula()返回當前單元格的公式。 MainWindow::updateStatusBar()調(diào)用了這個函數(shù)。
私有槽函數(shù) somethingChanged()中,如果 auto-recalculate為真,那么重新計算整個表格。然后發(fā)送 modified()信號。
小結(jié):想了解Qt更多的類,請到網(wǎng)上搜集就可以。關(guān)于Subclassing QTableWidget中從QTableWidget繼承的內(nèi)容介紹完了。希望本文對你有幫助!
【編輯推薦】