標籤:
Qt提供 QTableWidget作為表格的類以實現表格的準系統,表格中所裝載的每一個儲存格由類QTableWidgetItem提供。這是基於表格實現 Qt提供的一個基礎類,若想實現定製表格和儲存格的功能則需要派生重寫,使用Qt經典的MV結構 QTableView+QAbstractItemMode來實現。
關於QTableWidget+QTableWidgetItem使用方法簡介:
通常在使用這對組合以實現表格準系統時,通常的做法是:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
範例程式碼一:
QTableWidget* tableWidget = new QTableWidget;
tableWidget->setRowCount(11); // 設定表格的行數
tableWidget->setColumnCount(11); // 設定表格的列數
// 為表格的每一行每一列設定一個可以裝載資料的item
for(int nRow = 0; nRow < 11; nRow++)
{
for(int nColumn = 0; nColumn < 11; nColumn++);
{
QTableWidgetItem* item = new QTableWidgetItem;
tableWidget->setItem(nRow, nColumn, item);
}
}
// 通過索引訪問表格中的儲存格並賦值
QTableWidgetItem* item = tableWidget->itemAt(3, 3);
item->setText(“MyTableItem”);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
OK!如果你僅僅是動作表格的儲存格上述代碼沒有問題,但是如果你一旦涉及到表格的儲存格合并時,這樣動作表格就會出問題!
下面是筆者在開發過程中實現表格合并時遇到的一些問題及相關的解決方案:
問題一:如果按照範例程式碼一方式建立表格和儲存格進行表格合并時
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
tableWidget->setSpan(0, 0, 1, 11);
QTableWidgetItem* itemGet = tableWidget->itemAt(0, 0);
itemGet->setTextAlignment(Qt::AlignHCenter);
itemGet->setText(“MyTableItem(0, 0)”);
/* OK!上述代碼沒問題,實現第一行儲存格的合并和設定text */
itemGet = NULL;
itemGet = tableWidget->itemAt(1, 1);
itemGet->setTextAlignment(Qt::AlignHCenter);
itemGet->setText(“MyTableItem(1, 1)”);
/* Error!這裡就出問題了,itemAt(1, 1)返回的仍然是itemAt(0, 0)所指向的儲存格。就是由表格合并函數tableWidget->setSpan()所帶來的問題,表格合并使得itemAt()等相關的索引函數出現問題。(具體原因還不太清楚)*/
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
解決方案:
(1) 既然setSpan()函數破壞了itemAt()的索引,我們可以通過重建立立新的item的方式進行存取方法如下:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
QTableWidgetItem* newItem = new QTableWidgetItem;
tableWidget->setItem(1, 1, newItem);
newItem->setTextAlignment(Qt::AlignHCenter);
newItem->setText(“MyTableItem(1, 1)”);
/* 這樣就可以實現表格其它位置儲存格的賦值操作 */
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
(2) 不在建立QTableWidget時為儲存格動態建立QTableWidgetItem,而是在用到某個儲存格是再動態建立QTableWidgetItem。(推薦使用這種方法,避免記憶體泄露)
問題二:和問題一的情況相同都是由於索引而產生的,這次是由於selectedRange()索引錯誤而產生。
使用TableWidget產生表格後,希望通過滑鼠的選擇合併儲存格,這時會發現只有第一次調用selectedRange()能正確返回滑鼠所選擇的儲存格的範圍並執行合并成功,第二次以後selectedRanged()返回的永遠是滑鼠選擇範圍的第一儲存格。
解決方案:使用函數selectedRanges()。該函數將返回QList對象,裡麵包含了被滑鼠選擇的所有儲存格的位置,這樣我們就可以實現多次合并。代碼如下:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
tableWidget->setSpan(tableWidget->selectedRanges().first().topRow(),
tableWidget->selectedRanges().first().leftColumn(),
tableWidget->selectedRanges().last().bottomRow() –
tableWidget->selectedRanges().first().topRow() + 1,
tableWidget->selectedRanges().last().rightColumn() -
tableWidget->selectedRanges().first().leftColumn() + 1);
http://blog.chinaunix.net/uid-22159621-id-3049697.html
----------------------------------------------------------------------------------
Qt:多次合併儲存格的時要注意
如果一個QTableView使用setSpan合并後,資料更新後,還要繼續使用setSpan再次合并(主要是要對全表格進行重新的儲存格合并,已經合并過的地方行列又要重新進行新的合并,因為資料已經更新),這時不能直接使用setSpan,而是要先把QTableView的row還原為原來沒有合并行列的情形,再次使用setSpan,否則顯示很可能就會發生錯誤:
if (model != 0) {
// 恢複QTableView的為未合并前的樣子
for (int i = 0; i < model->rowCount(); ++i) {
ui->tableView->setSpan(i, 1, 1, 1);
ui->tableView->setSpan(i, 10, 1, 1);
}
}
// 合併儲存格
if (currentRow - firstRow != 1) {
ui->tableView->setSpan(firstRow, 1, rowSpan, 1);
ui->tableView->setSpan(firstRow, 10, rowSpan, 1);
}
http://www.cppblog.com/biao/archive/2009/12/11/102955.html
QTableWidget表格合并若干問題及解決方案