Qt基础教程之QStandardItemModel用法.docx
- 文档编号:27438999
- 上传时间:2023-07-01
- 格式:DOCX
- 页数:16
- 大小:71.05KB
Qt基础教程之QStandardItemModel用法.docx
《Qt基础教程之QStandardItemModel用法.docx》由会员分享,可在线阅读,更多相关《Qt基础教程之QStandardItemModel用法.docx(16页珍藏版)》请在冰豆网上搜索。
Qt基础教程之QStandardItemModel用法
本节介绍QStandardltemModel的使用,主要用到以下3个类:
1.QStandardItemModel:
基于项数据的标准数据模型,可以处理二维数据。
维护一个二维的项数据数组,每个项是一个QStandardltem类的变量,用于存储项的数据、字体格式、对齐方式等。
2.QTableView:
二维数据表视图组件,有多个行和多个列,每个基本显示单元是一个单元格,通过setModel()函数设置一个QStandardItemModel类的数据模型之后,一个单元格显示QStandardItemModel数据模型中的一个项。
3.QItemSelectionModel:
一个用于跟踪视图组件的单元格选择状态的类,当在QTableView选择某个单元格,或多个单元格时,通过QItemSelectionModel可以获得选中的单元格的模型索引,为单元格的选择操作提供方便。
这几个类之间的关系是:
QTableView是界面视图组件,其关联的数据模型是QStandardItemModel,关联的项选择模型是QItemSelectionModel,QStandardItemModel的数据管理的基本单元是QStandardItem。
实例中演示QStandardItemModel的使用,其运行时界面如图1所示。
图1运行时界面
该实例具有如下功能:
∙打开一个纯文本文件,该文件是规则的二维数据文件,通过字符串处理获取表头和各行各列的数据,导入到一个QStandardItemModel数据模型。
∙编辑修改数据模型的数据,可以插入行、添加行、删除行,还可以在QTableView视图组件中直接修改单元格的数据内容。
∙可以设置数据模型中某个项的不同角色的数据,包括文字对齐方式、字体是否粗体等。
∙通过QItemSelectionModel获取视图组件上的当前单元格,以及选择单元格的范围,对选择的单元格进行操作。
∙将数据模型的数据内容显示到QPlainTextEdit组件里,显示数据模型的内容,检验视图组件上做的修改是否与数据模型同步。
∙将修改后的模型数据另存为一个文本文件。
界面设计与主窗口类定义
主窗口类MainWindow里新增的定义如下(省略了UI设计器生成的界面组件的槽函数的声明):
#defineFixedColumnCount6//文件固定6列
classMainWindow:
publicQMainWindow
{
Q_OBJECTprivate:
QLabel*LabCurFile;//当前文件
QLabel*LabCellPos;//当前单元格行列号
QLabel*LabCellText;//当前单元格内容
QStandardItemModel*theModel;//数据模型
QItemSelectionModel*theSelection;//选择模型
voidiniModelFromStringList(QStringList&);//从StringList初始化数据模型
public:
explicitMainWindow(QWidget*parent=0);
privateslots:
//当前选择单元格发生变化
voidon_currentChanged(constQModelIndex¤t,constQModelIndex&previous);
private:
Ui:
:
MainWindow*ui;
};
这里定义了数据模型变量theModel,项数据选择模型变量theSelection。
定义的私有函数iniModelFromStringList()用于在打开文件时,从一个QStringList变量的内容创建数据模型。
自定义槽函数on_currentChanged()用于在TableView上选择单元格发生变化时,更新状态栏的信息显示,这个槽函数将会与项选择模型theSelection的currentChanged()信号关联。
QStandardltemModel的使用
系统初始化
在MainWindow的构造函数中进行界面初始化,数据模型和选择模型的创建,以及与视图组件的关联,信号与槽的关联等设置,代码如下:
MainWindow:
:
MainWindow(QWidget*parent):
QMainWindow(parent),ui(newUi:
:
MainWindow)
{
ui->setupUi(this);
setCentralWidget(ui->splitter);
theModel=newQStandardltemModel(2,FixedColumnCount,this);//数据模型
theSelection=newQItemSelectionModel(theModel);//选择模型
connect(theSelection,SIGNAL(currentChanged(QModelIndex,QModelIndex)),this,SLOT(on_currentChanged(QModelIndex,QModelIndex)));
ui->tableView->setModel(theModel);//设置数据模型
ui->tableVi.evi->setSelectionModel(theSelection);//设置选择模型
ui->tableView->setSelectionMode(QAbstractItemView:
:
ExtendedSelection);
ui->tableView->setSelectionBehavior(QAbstractItemView:
:
SelectItems);
//创建状态栏组件,代码略
}
在构造函数里首先创建数据模型theModel,创建数据选择模型时需要传递一个数据模型变量作为其参数。
这样,数据选择模型theSelection就与数据模型theModel关联,用于表示theModel的项数据选择操作。
创建数据模型和选择模型后,为TableView组件设置数据模型和选择模型:
ui->tableView->setModel(theModel);//设置数据模型
ui->tableView->setSelectionModel(theSelection);//设置选择模型
构造函数里还将自定义的槽函数on_currentChanged()与theSelection的currentChanged()信号关联,用于界面上tableView选择单元格发生变化时,显示单元格的行号、列号、内容等信息,槽函数代码如下:
voidMainWindow:
:
on_currentChanged(constQModelIndex¤t,constQModelIndex&previous)
{//选择单元格变化时的响应
if(current.isValid())
{
LabCellPos->setText(QString:
:
asprintf("当前单元格:
%d行,%d列",current.row(),current.column()));
QStandardItem*aItem=theModel->itemFromIndex(current);
this->LabCellText->setText("单元格内容:
"+aItem->text());
QFontfont=aItem->font();
ui->actFontBold->setChecked(font.bold());
}
}
从文本文件导入数据
QStandardItemModel是标准的基于项数据的数据模型,以类似于二维数组的形式管理内部数据,适合于处理表格型数据,其显示一般采用QTableView。
QStandardItemModel的数据可以是程序生成的内存中的数据,也可以来源于文件。
例如,在实际数据处理中,有些数据经常是以纯文本格式保存的,它们有固定的列数,每一列是一项数据,实际构成一个二维数据表。
图3纯文本格式的数据文件
下面是“打开文件”按钮的槽函数代码:
voidMainWindow:
:
on_actOpen_triggered()
{//打开文件
//QStringstr;
QStringcurPath=QCoreApplication:
:
applicationDirPath();//获取应用程序的路径
//调用打开文件对话框打开一个文件
QStringaFileName=QFileDialog:
:
getOpenFileName(this,"打开一个文件",curPath,"井数据文件(*.txt);;所有文件(*.*)");
if(aFileName.isEmpty())
return;//如果未选择文件,退出
QStringListfFileContent;//文件内容字符串列表
QFileaFile(aFileName);//以文件方式读出
if(aFile.open(QIODevice:
:
ReadOnly|QIODevice:
:
Text))//以只读文本方式打开文件
{
QTextStreamaStream(&aFile);//用文本流读取文件
ui->plainTextEdit->clear();//清空
while(!
aStream.atEnd())
{
QStringstr=aStream.readLine();//读取文件的一行
ui->plainTextEdit->appendPlainText(str);//添加到文本框显示
fFileContent.append(str);//添加到StringList
}
aFile.close();//关闭文件
this->LabCurFile->setText("当前文件:
"+aFileName);//状态栏显示
ui->actAppend->setEnabled(true);//更新Actions的enable属性
ui->actInsert->setEnabled(true);
ui->actDelete->setEnabled(true);
ui->actSave->setEnabled(true);
iniModelFromStringList(fFileContent);//从StringList的内容初始化数据模型
}
}
这段代码让用户选择所需要打开的数据文本文件,然后用只读和文本格式打开文件,逐行读取其内容,将每行字符串显示到界面上的plainTextEdit里,并且添加到一个临时的QStringList类型的变量fFileContent里。
然后调用自定义函数iniModelFromStringList(),用fFileContent的内容初始化数据模型。
下面是iniModelFromStringList()函数的代码:
voidMainWindow:
:
iniModelFromStringList(QStringList&aFileContent)
{//从一个StringList获取数据,初始化数据Model
introwCnt=aFileContent.count();//文本行数,第1行是标题
theModel->setRowCount(rowCnt-1);//实际数据行数
//设置表头
QStringheader=aFileContent.at(0);//第1行是表头
//一个或多个空格、TAB等分隔符隔开的字符串,分解为一个StringList
QStringListheaderList=header.split(QRegExp("\\s+"),QString:
:
SkipEmptyParts);
theModel->setHorizontalHeaderLabels(headerList);//设置表头文字
//设置表格数据
QStringaText;
QStringListtmpList;
intj;
QStandardItem*aItem;
for(inti=1;i { QStringaLineText=aFileContent.at(i);//获取数据区的一行 //一个或多个空格、TAB等分隔符隔开的字符串,分解为一个StringList QStringListtmpList=aLineText.split(QRegExp("\\s+"),QString: : SkipEmptyParts); for(j=0;j {//不包含最后一列 aItem=newQStandardItem(tmpList.at(j));//创建item theModel->setItem(i-1,j,aItem);//为模型的某个行列位置设置Item } aItem=newQStandardItem(headerList.at(j));//最后一列是Checkable,需要设置 //aItem=newQStandardItem();//最后一列是Checkable,设置 aItem->setCheckable(true);//设置为Checkable //aItem->setTextAlignment(Qt: : AlignHCenter); if(tmpList.at(j)=="0") aItem->setCheckState(Qt: : Unchecked);//根据数据设置check状态 else aItem->setCheckState(Qt: : Checked); theModel->setItem(i-1,j,aItem);//为模型的某个行列位置设置Item } } 传递来的参数aFileContent是文本文件所有行构成的StringList,文件的每一行是aFileContent的一行字符串,第1行是表头文字,数据从第2行开始。 程序首先获取字符串列表的行数,然后设置数据模型的行数,因为数据模型的列数在初始化时己经设置了。 然后获取字符串列表的第1行,即表头文字,用QString: : split()函数分割成一个QStringList,设置为数据模型的表头标题。 QString: : split()函数根据某个特定的符号将字符串进行分割。 例如,header是数据列的标题,每个标题之间通过一个或多个TAB键分隔,其内容是: 测深(m)垂深(m)方位(°)总位移(m)固井质量测井取样 那么通过上面的split()函数操作,得到一个字符串列表headerList,其内容是: 测深(m) 垂深(m) 方位(°) 总位移(m) 固井质量 测井取样 也就是分解为一个6行的StringList。 然后使用此字符串列表作为数据模型,设置表头标题的函数setHorizontalHeaderLabels()的参数,就可以为数据模型设置表头了。 同样,在逐行获取字符串后,也采用split()函数进行分解,为每个数据创建一个QStandardltem类型的项数据altem,并赋给数据模型作为某行某列的项数据。 QStandardItemModel以二维表格的形式保存项数据,每个项数据对应着QTableView的一个单元格。 项数据不仅可以存储显示的文字,还可以存储其他角色的数据。 数据文件的最后一列是一个逻辑型数据,在tableView上显示时为其提供一个CheckBox组件,此功能通过调用QStandardItem的setCheckable()函数实现。 数据修改 当TableView设置为可编辑时,双击一个单元格可以修改其内容,对于使用CheckBox的列,改变CheckBox的勾选状态,就可以修改单元格关联项的选择状态。 在实例主窗口工具栏上有“添加行”、“插入行”、“删除行”按钮,它们实现相应的编辑操作,这些操作都是直接针对数据模型的,数据模型被修改后,会直接在TableView上显示出来。 添加行 “添加行”操作是在数据表的最后添加一行,其实现代码如下: voidMainWindow: : on_actAppend_triggered() {//在表格最后添加行 QList QStandardItem*aItem; for(inti=0;i { aItem=newQStandardItem("0");//创建Item aItemList< } //获取最后一列的表头文字 QStringstr=theModel->headerData(theModel->columnCount()-1,Qt: : Horizontal,Qt: : DisplayRole).toString(); aItem=newQStandardItem(str);//创建"测井取样"Item aItem->setCheckable(true); aItemList< theModel->insertRow(theModel->rowCount(),aItemList);//插入一行,需要每个Cell的Item QModelIndexcurIndex=theModel->index(theModel->rowCount()-1,0);//创建最后一行的ModelIndex theSelection->clearSelection();//清空选择项 theSelection->setCurrentIndex(curIndex,QItemSelectionModel: : Select);//设置刚插入的行为当前选择行 } 使用QStandardltemModel: : insertRow()函数插入一行,其函数原型是: voidinsertRow(introw,constQList 其中,row是一个行号,表示在此行号之前插入一行,若row等于或大于总行数,则在最后添加一行。 QList 在这段程序中,为前5列创建QStandardItem对象时,都使用文字“0”,最后一列使用表头的标题,并设置为Checkable。 创建完每个项数据对象后,使用insertRow()函数在最后添加一行。 插入行 “插入行”按钮的功能是在当前行的前面插入一行,实现代码与“添加行”类似。 删除行 “删除行”按钮的功能是删除当前行,首先从选择模型中获取当前单元格的模型索引,然后从模型索引中获取行号,调用removeRow(introw)删除指定的行。 voidMainWindow: : on_actDelete_triggered() {//删除行 QModelIndexcurIndex=theSelection->currentIndex();//获取模型索引 if(curIndex.row()==theModel->rowCount()-1)//最后一行 theModel->removeRow(curIndex.row());//删除最后一行 else{ theModel->removeRow(curIndex.row());//删除一行,并重新设置当前选择行 theSelection->setCurrentIndex(curIndex,QItemSelectionModel: : Select); } } 单元格格式设置 工具栏上有3个设置单元格文字对齐方式的按钮,还有一个设置字体粗体的按钮。 当在TableView中选择多个单元格时,可以同时设置多个单元格的格式。 例如,“居左”按钮的代码如下: voidMainWindow: : on_actAlignLeft_triggered() {//设置文字居左对齐 if(! theSelection->hasSelection()) return; //获取选择的单元格的模型索引列表,可以是多选 QModelIndexListselectedIndex=theSelection->selectedIndexes(); for(inti=0;i { QModelIndexaIndex=selectedIndex.at(i);//获取一个模型索引 QStandardItem*aItem=theModel->itemFromIndex(aIndex); aItem->setTextAlignment(Qt: : AlignLeft);//设置文字对齐方式 } } QItemSelectionModel: : selectedIndexes()函数返回选择单元格的模型索引列表,然后通过此列表获取每个选择的单元格的模型索引,再通过模型索引获取其项数据,然后调用QStandardItem: : setTextAlignment()设置一个项的对齐方式即可。 “居中”和“居右”按钮的代码与此类似。 “粗体”按钮设置单元格的字体是否为粗体,在选择单元格时,actFontBold的check状态根据当前单元格的字体是否为粗体自动更新。 actFontBold的triggered(bool)的槽函数代码如下,与设置对齐方式的代码操作方式类似: voidMainWindow: : on_actFontBold_triggered(boolchecked) {//设置字体粗体 if(! theSelection->hasSelection()) return; //获取选择单元格的模型索引列表 QModelIndexListselectedIndex=theSelection->selectedIndexes(); for(inti=0;i
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Qt 基础教程 QStandardItemModel 用法