我是靠谱客的博主 隐形橘子,最近开发中收集的这篇文章主要介绍Qt:26---QStandardItemModel数据模型一、QStandardItemModel类的基本功能二、QItemSelectionModel类三、QModelIndex、QModelIndexList类四、常用函数五、演示案例,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一、QStandardItemModel类的基本功能

  • QStandardItemModel是标准的以项数据为基础的标准数据模型类
  • QStandardItemModel通常与QTableView组合成数据模型,实现通用的二维数据的管理功能
  • QStandardItemModel维护一个二维的项数据数组,每个项是一个QStandarItem类对象,用于存储项的数据、字体格式、对齐方式等

二、QItemSelectionModel类

  • 概念:一个用于跟踪视图组件的单元格选择状态的类。QTableView与QStandardItemModel数据模型组合后,在QTableView选择某个/多个单元格后,这些单元格就组合成一个QItemSelectionModel类对象
  • 是一个选择模型

三、QModelIndex、QModelIndexList类

  • QModelIndex:获得当前数据模型的索引,通过QModelIndex QStandardItemModel::index(int row, int column, const QModelIndex &parent = QModelIndex()) const、QModelIndex QItemSelectionModel::currentIndex() const函数获取,或者QModelIndexList的at函数获取
  • QModelIndexList:获得当前数据模型的索引集合,通过QModelIndexList QItemSelectionModel::selectedIndexes() const函数获得

四、常用函数

//通过数据模型索引获得QStandardItem 对象
QStandardItem *QStandardItemModel::itemFromIndex(const QModelIndex &index) const

//为QStandardItemModel数据模型设置表头
void QStandardItemModel::setHorizontalHeaderLabels(const QStringList &labels)

//为QStandardItemModel数据模型的指定行、列设置QStandardItem对象
void QStandardItemModel::setItem(int row, int column, QStandardItem *item)

//将QStandardItem对象设置为CheckBox状态(选中/未选中)
void QStandardItem::setCheckState(Qt::CheckState state)

//获取表头数据
QVariant QStandardItemModel::headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const

//在row行之前插入一个QList集合的对象
void QStandardItemModel::insertRow(int row, const QList<QStandardItem *> &items)

五、演示案例

功能实现

工具栏使用到的Action

类的定义

  • 类中的初始化变量、函数、宏定义

类构造函数

on_currentChanged槽函数

//鼠标选中tabView单元格变化时,在状态栏显示行、列号,内容等信息
void MainWindow::on_currentChanged(const QModelIndex &current,const QModelIndex &previous)
{
    if(current.isValid())
    {
        LabCellPos->setText(QString::asprintf("current:%d row,%d col",current.row(),current.column()));
        QStandardItem* aItem=theModel->itemFromIndex(current);//获得当前项对象
        this->LabCellText->setText("Current content:"+aItem->text());//获得当前项的内容,并显示
        QFont font=aItem->font();
        ui->actFontBold->setChecked(font.bold());
    }
}

文件打开triggered函数、与自定义函数iniModelFromStringList

  • 文件打开triggered的函数会打开一个已经书写规范的文件,然后读取这些文件的数据,存放在一个QStringList对象中,然后将QStringList对象作为iniModelFromStringList函数的参数调用该函数,然后iniModelFromStringList将这些数据显示到tabView中
  • 最后一列“测井取样”为布尔值,在设置tabView时,我们将最后一列设置为CheckBox对象
  • QString::split()函数用来分割成一个QString对象分割为QStringList对象

void MainWindow::on_actOpen_triggered()
{
    QString curPath=QCoreApplication::applicationDirPath();//获得当前路径
    //打开一个文件
    QString aFileName=QFileDialog::getOpenFileName(this,
             QStringLiteral("打开一个文件"),curPath,QStringLiteral("井数据文件(*.txt);;所有文件(*.*)"));
    if(aFileName.isEmpty())
        return;
    QStringList fFileContent;
    QFile aFile(aFileName);//将打开的文件创建一个QFile对象
    if(aFile.open(QIODevice::ReadOnly|QIODevice::Text))//以文本、只读的方式读取文件
    {
        QTextStream aStream(&aFile);
        ui->plainTextEdit->clear();
        while(!aStream.atEnd())//循环读取文件
        {
            QString str=aStream.readLine();//读取一行数据
            ui->plainTextEdit->appendPlainText(str);
            fFileContent.append(str);//将读取到的数据添加到QStringList对象中
        }
        aFile.close();
        this->LabCurFile->setText(QStringLiteral("当前文件:")+aFileName);
        iniModelFromStringList(fFileContent);
    }
}

void MainWindow::iniModelFromStringList(QStringList &aFileContent)
{
    int rowCnt=aFileContent.count();//获取文本的行数
    theModel->setRowCount(rowCnt-1);

    //设置表头,一个或多个空格、TAB等分隔符隔开的字符串,分解为一个StringList
    QString header=aFileContent.at(0);//获取第一行数据,将数据作为tabView的表头
    QStringList headerList=header.split(QRegExp("\s+"),QString::SkipEmptyParts);//调用split函数分割数据
    theModel->setHorizontalHeaderLabels(headerList);//将分割好的QStringList作为QStandardItemModel模型的表头数据

    //设置表格数据
    QStandardItem* aItem;//每一个项
    QStringList tmpList;
    int j;
    for(int i=1;i<rowCnt;++i)//循环遍历行
    {
        //获取行数据,然后进行分割
        QString aLineText=aFileContent.at(i);
        tmpList=aLineText.split(QRegExp("\s+"),QString::SkipEmptyParts);

        for(j=0;j<FixedColumnCount-1;j++)//循环改行数据,并将每一项作为列数据
        {
            //不包含最后一列
            aItem=new QStandardItem(tmpList.at(j));
            theModel->setItem(i-1,j,aItem);
        }
        //最后一列
        aItem=new QStandardItem(headerList.at(j));
        aItem->setCheckable(true);//先将最后一列设置为选中
        if(tmpList.at(j)=="0")//如果最后一列为0,则设置为未选中
            aItem->setCheckState(Qt::Unchecked);
        else//如果最后一列为1,则设置为选中
            aItem->setCheckState(Qt::Checked);
        theModel->setItem(i-1,j,aItem);//设置最后一列
    }
}

添加行按钮触发函数(act_Append_triggered)

  • void QStandardItemModel::insertRow(int row, const QList<QStandardItem *> &items)  //该函数在row行之前插入一行数据,数据为参数2QList的集合
  • void QStandardItemModel::insertRow(int row, QStandardItem *item)  //该函数在row行之前插入一个QStandardItem对象

void MainWindow::on_actAppend_triggered()
{
    QList<QStandardItem*> aItemList;//一个集合,用来保存QStandardItem项
    QStandardItem *aItem;
    //循环列数,只循环前5列,并且创建QStandardItem对象存放在QList集合中
    for(int i=0;i<FixedColumnCount-1;++i)
    {
        aItem=new QStandardItem("0");//每一个项的内容初始化为0
        aItemList<<aItem;
    }

    //因为最后一列为CheckBox,所以特殊处理
    //获得最后一列的标头标题
    QString str=theModel->headerData(theModel->columnCount()-1,Qt::Horizontal,
      Qt::DisplayRole).toString();
    aItem=new QStandardItem(str);//将标头标题设置为最后一列的内容
    aItem->setCheckable(true);//最后一列设置为选择状态
    aItemList<<aItem;

    //在rowCount()行之前插入一行数据,aItemList为插入的集合
    theModel->insertRow(theModel->rowCount(),aItemList);

    //获得一行的索引
    QModelIndex curIndex=theModel->index(theModel->rowCount()-1,0);
    theSelection->clearSelection();//清除选择模型
    //将当前的选择对象设置为最后一行
    theSelection->setCurrentIndex(curIndex,QItemSelectionModel::Select);
}

插入行按钮触发函数(actInsert_triggered)

  • 与添加行按钮的代码类似,只是将insertRow的参数1改为当前选择的索引即可,就是在当前的索引处插入一行新数据

删除行按钮触发函数(actDelete_triggered

  • bool QAbstractItemModel::removeRow(int row, const QModelIndex &parent = QModelIndex()) //删除指定的行
  • 下面的代码为什么要判断是否为最后一行,因为QStandardItemModel数据模型刚打开的时候是没有处于选择状态的
void MainWindow::on_actDelete_triggered()
{
    QModelIndex curIndex=theSelection->currentIndex();//获取当前的模型索引
    if(curIndex.row()==theModel->rowCount()-1)//如果选择的索引为最后一行
        theModel->removeRow(curIndex.row());//删除最后一行
    else//如果选择的不是最后一行
    {
        theModel->removeRow(curIndex.row());//删除改行
        //重新设置模型索引
        theSelection->setCurrentIndex(curIndex,QItemSelectionModel::Select);
    }
}

居左、居中、居右按钮触发函数(actAlignLeft_triggered)

  • setTextAlignment() //用来这是QStandardItem对象的对齐方式
  • 下面只演示向左对齐的,居中与向右对齐只需要改变setTextAlignment函数的参数即可
void MainWindow::on_actAlignLeft_triggered()
{
    if(!theSelection->hasSelection())//如果当前没有选中单元格,直接退出
        return;
    //获取选中的单元格索引列表,存放在QModelIndexList对象中
    QModelIndexList selectIndex=theSelection->selectedIndexes();
    for(int i=0;i<selectIndex.count();++i)//遍历QModelIndexList对象
    {
        QModelIndex aIndex=selectIndex.at(i);//获取模型索引
        QStandardItem* aItem=theModel->itemFromIndex(aIndex);//根据模型索引获得QStandardItem对象
        aItem->setTextAlignment(Qt::AlignLeft);//设置该对象文字向左对齐
    }
}

粗体按钮触发函数(actFontBold_triggered)

  • void QStandardItem::setFont(const QFont &font) //设置项的字体格式
void MainWindow::on_actFontBold_triggered()
{
    if(!theSelection->hasSelection())//如果当前没有选中单元格,直接退出
        return;
    //获取 选中选中的单元格索引列表,存放在QModelIndexList对象中
    QModelIndexList selectIndex=theSelection->selectedIndexes();
    for(int i=0;i<selectIndex.count();++i)//遍历QModelIndexList对象
    {
        QModelIndex aIndex=selectIndex.at(i);//获取模型索引
        QStandardItem* aItem=theModel->itemFromIndex(aIndex);//根据模型索引获得QStandardItem对象
        QFont font=aItem->font();//获得字体对象
        font.setBold(true);//将字体为粗体
        aItem->setFont(font);//为该项设置字体对象
    }
}

另存文件按钮触发函数(actSave_triggered)

  • 点击该按钮,可以将数据模型的数据另存为一个数据文本文件,同时也显示在PlainTextEdit里
  • 注意:该函数还有问题,待解决
void MainWindow::on_actSave_triggered()
{
    QString curPath=QCoreApplication::applicationDirPath();//获得当前路径
    QString aFileName=QFileDialog::getSaveFileName(this,QStringLiteral("选择一个文件"),
           curPath,QStringLiteral("井斜数据文件(*.txt);;所有文件(*.*)"));//设置一个保存文件
    if(aFileName.isEmpty())
        return;
    QFile aFile(aFileName);//为保存文件设置QFile对象
    if(!(aFile.open(QIODevice::ReadWrite|QIODevice::Text|QIODevice::Truncate)))
        return;
    QTextStream aStream(&aFile);//为保存文件设置文件流对象

    QStandardItem* aItem;
    int i,j;
    QString str;//创建一个QString对象,用来保存
    ui->plainTextEdit->clear();

    for(int i=0;i>theModel->columnCount();++i)//遍历列数
    {
        aItem=theModel->horizontalHeaderItem(i);//先将表头数据保存到QString中
        str=str+aItem->text()+"t";
    }
    aStream<<str<<"n";//换行
    ui->plainTextEdit->appendPlainText(str);

    for(i=0;i<theModel->rowCount();++i)//遍历行数
    {
        str="";
        for(j=0;i<theModel->columnCount()-1;j++)//遍历列数,不包括最后一列
        {
            aItem=theModel->item(i,j);
            str=str+aItem->text()+QString::asprintf("t");
        }
        //最后一列特殊处理
        aItem=theModel->item(i,j);
        if(aItem->checkState()==Qt::Checked)
            str=str+"1";
        else
            str=str+"0";
        ui->plainTextEdit->appendPlainText(str);
        aStream<<str<<"n";
    }
}

数据模型预览按钮触发函数

  • 与数据另存为文件按钮的功能类似,就是将数据模型的数据显示到右侧的PlainTextEdit里面

最后

以上就是隐形橘子为你收集整理的Qt:26---QStandardItemModel数据模型一、QStandardItemModel类的基本功能二、QItemSelectionModel类三、QModelIndex、QModelIndexList类四、常用函数五、演示案例的全部内容,希望文章能够帮你解决Qt:26---QStandardItemModel数据模型一、QStandardItemModel类的基本功能二、QItemSelectionModel类三、QModelIndex、QModelIndexList类四、常用函数五、演示案例所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(58)

评论列表共有 0 条评论

立即
投稿
返回
顶部