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

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