QTableView、QStandardItemModel、QItemSelectionModel的使用介紹

控件介紹

  • QTableView
    二維數據表視圖組件,有多個行和多個列,每個基本顯示單元是一個單元格,通過 setModel() 函數設置一個QStandardItemModel 類的數據模型之後,一個單元格顯示 QStandardItemModel 數據模型中的一個項。
  • QStandardItemModel
    基於項數據的標準數據模型,可以處理二維數據。維護一個二維的項數據數組,每個項是一個 QStandardltem 類的變量,用於存儲項的數據、字體格式、對齊方式等。
  • QItemSelectionModel
    一個用於跟蹤視圖組件的單元格選擇狀態的類,當在 QTableView 選擇某個單元格,或多個單元格時,通過QItemSelectionModel 可以獲得選中的單元格的模型索引,爲單元格的選擇操作提供方便。

QAbstractItemView::SelectionMode的介紹

Constant Value Description
QAbstractItemView::SingleSelection 1 當用戶選擇一個項目時,任何已經選擇的項目將變爲未選擇。用戶可以取消選擇所選項目
QAbstractItemView::ContiguousSelection 4 當用戶以通常的方式選擇一個項目時,選擇被清除並選擇新項目。但是,如果用戶在單擊某個項目時按下Shift鍵,則會選擇或取消當前項目和已單擊項目之間的所有項目,具體取決於已單擊項目的狀態
QAbstractItemView::ExtendedSelection 3 當用戶以通常的方式選擇一個項目時,選擇被清除並選擇新項目。但是,如果用戶在單擊項目時按下Ctrl鍵,則所單擊的項目將被切換,而其他所有項目將保持不變。如果用戶在單擊某個項目時按下Shift鍵,則會選擇或取消當前項目和已單擊項目之間的所有項目,具體取決於已單擊項目的狀態。可以通過拖動鼠標在多個項目上進行選擇
QAbstractItemView::MultiSelection 2 當用戶以通常的方式選擇一個項目時,該項目的選擇狀態是切換的,而其他項目將保持不變。多個項目可以通過拖動鼠標來進行切換
QAbstractItemView::NoSelection 0 無法選擇項目

QAbstractItemView::SelectionBehavior的介紹

Constant Value Description
QAbstractItemView::SelectItems 0 Selecting single items
QAbstractItemView::SelectRows 1 Selecting only rows
QAbstractItemView::SelectColumns 2 Selecting only columns

QAbstractItemView::EditTrigger 的介紹

Constant Value Description
QAbstractItemView::NoEditTriggers 0 不可能編輯
QAbstractItemView::CurrentChanged 1 當前項發生變化時,開始編輯
QAbstractItemView::DoubleClicked 2 當雙擊一個項目時,開始編輯
QAbstractItemView::SelectedClicked 4 當單擊一個已經選擇的項目時進行編輯
QAbstractItemView::EditKeyPressed 8 當在一個項目上按下平臺編輯鍵時進行編輯
QAbstractItemView::AnyKeyPressed 16 當按下一個項目上的任何鍵時進行編輯
QAbstractItemView::AllEditTriggers 31 開始對以上所有操作進行編輯

下面試具體使用:

m_StandardItemModel = new QStandardItemModel(this);
m_ItemSelectionModel = new QItemSelectionModel(m_StandardItemModel);

m_TableView = new QTableView(this);
m_TableView->setModel(m_StandardItemModel);
m_TableView->setSelectionModel(m_ItemSelectionModel);
m_TableView->setSelectionMode(QAbstractItemView::SingleSelection);  // 選擇單項
m_TableView->setSelectionBehavior(QAbstractItemView::SelectRows);   // 選擇整行
m_TableView->setEditTriggers(QAbstractItemView::NoEditTriggers);    // 不可編輯

m_TableView->horizontalHeader()->setVisible(false);                 // 水平不可見
m_TableView->verticalHeader()->setVisible(false);                   // 垂直不可見

添加元素

int iCurRow = m_StandardItemModel->rowCount();
QList<QStandardItem*> aItemList; //容器類
QStandardItem   *aItem;
for(int i = 0; i < 4; i++) //不包含最後1列
{
	aItem = new QStandardItem(QString("%1, %2").arg(iCurRow).arg(i)); //創建Item
    aItem->setTextAlignment(Qt::AlignCenter); //設置文字對齊方式
    QFont font=aItem->font();   //獲取字體
    font.setBold(true);         //設置字體是否粗體
    aItem->setFont(font);       //重新設置字體
    aItemList << aItem;         //添加到容器
}
m_StandardItemModel->insertRow(iCurRow, aItemList); //插入一行,需要每個Cell的Item
QModelIndex curIndex = m_StandardItemModel->index(iCurRow, 0);//創建最後一行的ModelIndex
m_ItemSelectionModel->clearSelection();//清空選擇項
m_ItemSelectionModel->setCurrentIndex(curIndex, QItemSelectionModel::Select);//設置剛插入的行爲當前選擇行

刪除元素

// 判斷模型中是否還有數據
if(m_StandardItemModel->rowCount() == 0)
{
	QMessageBox::critical(this, tr("出現錯誤"), tr("無法刪除:沒有可刪除數據"));
	return;
}

QModelIndex curIndex= m_ItemSelectionModel->currentIndex() ;//獲取模型索引
if(curIndex.row() == -1) // 判斷是否有選中數據
{
	QMessageBox::critical(this, tr("出現錯誤"), tr("無法刪除:未選中數據"));
	return;
}
else
{
	m_StandardItemModel->removeRow(curIndex.row()) ; //刪除一行
	QModelIndex index= m_StandardItemModel->index(curIndex.row() - 1,1);
	m_TableView->setCurrentIndex(index);             //選定上一行
}

上下移動

// 上移
int iCurrentRow = m_TableView->currentIndex().row();//獲取當前行的Index

if (iCurrentRow != -1)//如果選中了數據,(未選擇數據之前,返回值是-1)
{
	if (iCurrentRow != 0)//如果選定行不在第一行
 	{
		swapTwoRow(iCurrentRow, iCurrentRow - 1, m_StandardItemModel);
		QModelIndex index= m_StandardItemModel->index(iCurrentRow - 1,1);
		m_TableView->setCurrentIndex(index);//移動過後繼續選定該行
	}
}
else
{
	if (m_StandardItemModel->rowCount() != 0)//如果有數據,但是currentRow=--1 說明沒有選擇數據,把焦點定位到第一行
	{
		QMessageBox::critical(this, tr("出現錯誤"), tr("無法移動:未選中數據"));
	}
	else
    {	
    	QMessageBox::critical(this, tr("出現錯誤"), tr("無法移動:表格沒有數據"));
    }
}

// 下移
int iCurrentRow = m_TableView->currentIndex().row();

if (iCurrentRow != -1)//如果選中了一行
{
	if (iCurrentRow != (m_StandardItemModel->rowCount() - 1))//如果不是最後一行
    {
		swapTwoRow(iCurrentRow, iCurrentRow + 1, m_StandardItemModel);
		QModelIndex index=m_StandardItemModel->index(iCurrentRow + 1,1);
        m_TableView->setCurrentIndex(index);//移動過後繼續選定該行
	}
}
else
{
	if (m_StandardItemModel->rowCount() != 0)//如果有數據,但是currentRow=--1 說明沒有選擇數據,把焦點定位到第一行
	{
		QMessageBox::critical(this, tr("出現錯誤"), tr("無法移動:未選中數據"));
	}
	else
	{
		QMessageBox::critical(this, tr("出現錯誤"), tr("無法移動:表格沒有數據"));
	}
}

// 交換兩行數據
void MainWindow::swapTwoRow(int selectRow, int targetRow,QStandardItemModel *Model)
{
    QStringList selectRowLine, targetRowLine;//創建兩個QStringList用於儲存表格數據

    for (int i = 0; i < m_StandardItemModel->columnCount(); i++)
    {
        selectRowLine.append(Model->item(selectRow,i)->text());//獲取文本,並添加進QStringLine
        targetRowLine.append(Model->item(targetRow,i)->text());
    }

    for (int i = 0; i < m_StandardItemModel->columnCount(); i++)
    {
        Model->setData(Model->index(selectRow, i), targetRowLine.at(i));
        Model->setData(Model->index(targetRow, i), selectRowLine.at(i));
//        Model->setItem(selectRow, i, new QStandardItem(targetRowLine.at(i)));//設置文本
//        Model->setItem(targetRow, i, new QStandardItem(selectRowLine.at(i)));
//        Model->item(selectRow, i)->setTextAlignment(Qt::AlignCenter);
//        Model->item(targetRow, i)->setTextAlignment(Qt::AlignCenter);
    }
}

清空表格

m_StandardItemModel->clear();

示例代碼:
https://download.csdn.net/download/bloke_come/12565014

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章