c/c++开发分享C/C++中的 Qt StandardItemModel 数据模型应用解析

qstandarditemmodel 是标准的以项数据为单位的基于m/v模型的一种标准数据管理方式,model/view 是qt中的一种数据编排结构,其中model代表模型,view代表视图,视图是显

qstandarditemmodel 是标准的以项%ignore_a_1%为单位的基于m/v模型的一种标准数据管理方式,model/view 是qt中的一种数据编排结构,其中model代表模型,view代表视图,视图是显示和编辑数据的界面组件,而模型则是视图与原始数据之间的接口,通常该类结构都是用在数据库中较多,例如模型结构负责读取或写入数据库,视图结构则负责展示数据,其条理清晰,编写代码便于维护。

qstandarditemmodel组件通常会配合tableview组件一起使用,当数据库或文本中的记录发生变化时会自动同步到组件中,首先绘制ui界面。

C/C++中的 Qt StandardItemModel 数据模型应用解析

其次绑定顶部toolbar菜单,分别对菜单增加对应的功能属性的描述等。

C/C++中的 Qt StandardItemModel 数据模型应用解析

初始化构造函数: 当程序运行时,我们需要对页面中的控件逐一初始化,并将table表格与模型通过调用ui->tableview->setmodel(model)进行绑定。

  #include "mainwindow.h"  #include "ui_mainwindow.h"    #include <iostream>  #include <qlabel>  #include <qstandarditem>  #include <qitemselectionmodel>    #include <qfiledialog>  #include <qtextstream>    #include <qlist>    // 默认构造函数  // https://www.cnblogs.com/lyshark  mainwindow::mainwindow(qwidget *parent): qmainwindow(parent), ui(new ui::mainwindow)  {      ui->setupui(this);        // 初始化部分      model = new qstandarditemmodel(3,fixedcolumncount,this);  // 数据模型初始化      selection = new qitemselectionmodel(model);               // item选择模型        // 为tableview设置数据模型      ui->tableview->setmodel(model);               // 设置数据模型      ui->tableview->setselectionmodel(selection);  // 设置选择模型        // 默认禁用所有action选项,只保留打开      ui->actionsave->setenabled(false);      ui->actionview->setenabled(false);      ui->actionappend->setenabled(false);      ui->actiondelete->setenabled(false);      ui->actioninsert->setenabled(false);        // 创建状态栏组件,主要来显示单元格位置      labcurfile = new qlabel("当前文件:",this);      labcurfile->setminimumwidth(200);        labcellpos = new qlabel("当前单元格:",this);      labcellpos->setminimumwidth(180);      labcellpos->setalignment(qt::alignhcenter);        labcelltext = new qlabel("单元格内容:",this);      labcelltext->setminimumwidth(150);        ui->statusbar->addwidget(labcurfile);      ui->statusbar->addwidget(labcellpos);      ui->statusbar->addwidget(labcelltext);        //选择当前单元格变化时的信号与槽      connect(selection,signal(currentchanged(qmodelindex,qmodelindex)),this,slot(on_currentchanged(qmodelindex,qmodelindex)));  }    mainwindow::~mainwindow()  {      delete ui;  }

初始化时同时需要绑定一个on_currentchanged(qmodelindex,qmodelindex)信号,当用户选中指定单元格时相应用户。

  // 选择单元格变化时的响应,通过在构造函数中绑定信号和槽函数实现触发  // https://www.cnblogs.com/lyshark  void mainwindow::on_currentchanged(const qmodelindex &current, const qmodelindex &previous)  {     q_unused(previous);        if (current.isvalid()) //当前模型索引有效      {          labcellpos->settext(qstring::asprintf("当前单元格:%d行,%d列",current.row(),current.column())); //显示模型索引的行和列号          qstandarditem   *aitem;          aitem=model->itemfromindex(current); //从模型索引获得item          this->labcelltext->settext("单元格内容:"+aitem->text()); //显示item的文字内容      }  }

当页面被初始化时,默认界面如下:

C/C++中的 Qt StandardItemModel 数据模型应用解析

打开并填充组件: 当工具栏中打开文件被点击后则触发,打开文件时通过afile.open打开,循环读入文件,并将文件中的内容逐行追加到qstringlist ffilecontent中,当追加完毕后,直接调用inimodelfromstringlist(ffilecontent);完成对页面tableview组件的初始化,并设置其他控件状态为可点击。

  void mainwindow::on_actionopen_triggered()  {      qstring curpath=qcoreapplication::applicationdirpath(); // 获取应用程序的路径            // 调用打开文件对话框打开一个文件      // https://www.cnblogs.com/lyshark      qstring afilename=qfiledialog::getopenfilename(this,"打开一个文件",curpath,"数据文件(*.txt);;所有文件(*.*)");      if (afilename.isempty())      {          return; // 如果未选择文件则退出      }        qstringlist ffilecontent;                              // 文件内容字符串列表      qfile afile(afilename);                                // 以文件方式读出      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);                // 添加到stringlist          }          afile.close();                               // 关闭文件            inimodelfromstringlist(ffilecontent);        // 从stringlist的内容初始化数据模型      }        // 打开文件完成后,就可以将action全部开启了      ui->actionsave->setenabled(true);      ui->actionview->setenabled(true);      ui->actionappend->setenabled(true);      ui->actiondelete->setenabled(true);      ui->actioninsert->setenabled(true);        // 打开文件成功后,设置状态栏当前文件列      this->labcurfile->settext("当前文件:"+afilename);//状态栏显示  }

如上inimodelfromstringlist(ffilecontent);函数是后期增加的,我们需要自己实现,该函数的作用是从传入的stringlist中获取数据,并将数据初始化到tableview模型中,实现代码如下。

  void mainwindow::inimodelfromstringlist(qstringlist& afilecontent)  {      int rowcnt=afilecontent.count();     // 文本行数,第1行是标题      model->setrowcount(rowcnt-1);        // 实际数据行数,要在标题上减去1        // 设置表头      qstring header=afilecontent.at(0);         // 第1行是表头        // 一个或多个空格、tab等分隔符隔开的字符串、分解为一个stringlist      // https://www.cnblogs.com/lyshark      qstringlist headerlist=header.split(qregexp("\s+"),qstring::skipemptyparts);      model->sethorizontalheaderlabels(headerlist); // 设置表头文字        // 设置表格中的数据      int x = 0,y = 0;      qstandarditem *item;        // 有多少列数据就循环多少次      // https://www.cnblogs.com/lyshark      for(x=1; x < rowcnt; x++)      {          qstring linetext = afilecontent.at(x);    // 获取数据区的一行            // 一个或多个空格、tab等分隔符隔开的字符串、分解为一个stringlist          qstringlist tmplist=linetext.split(qregexp("\s+"),qstring::skipemptyparts);            // 循环列数,也就是循环fixedcolumncount,其中tmplist中的内容也是.          for(y=0; y < fixedcolumncount-1; y++)          {              item = new qstandarditem(tmplist.at(y)); // 创建item              model->setitem(x-1,y,item);              // 为模型的某个行列位置设置item          }            // 最后一个数据需要取出来判断,并单独设置状态          item=new qstandarditem(headerlist.at(y));   // 最后一列是checkable,需要设置          item->setcheckable(true);                   // 设置为checkable            // 判断最后一个数值是否为0          if (tmplist.at(y) == "0")              item->setcheckstate(qt::unchecked);   // 根据数据设置check状态          else              item->setcheckstate(qt::checked);            model->setitem(x-1,y,item); //为模型的某个行列位置设置item      }  }

初始化组件后效果如下:

C/C++中的 Qt StandardItemModel 数据模型应用解析

实现添加一行数据: 为tableview添加一行数据,在文件末尾插入。

  void mainwindow::on_actionappend_triggered()  {      qlist<qstandarditem *> itemlist;   // 创建临时容器      qstandarditem *item;        // 模拟添加一列的数据      for(int x=0; x<fixedcolumncount-1; x++)      {          item = new qstandarditem("测试(追加行)");    // 循环创建每一列          itemlist << item;                          // 添加到链表中      }        // 创建最后一个列元素,由于是选择框所以需要单独创建      // https://www.cnblogs.com/lyshark      // 1.获取到最后一列的表头下标,最后下标为6      qstring str = model->headerdata(model->columncount()-1,qt::horizontal,qt::displayrole).tostring();        item=new qstandarditem(str); // 创建 "是否合格" 字段      item->setcheckable(true);    // 设置状态为真      itemlist << item;            // 最后一个选项追加进去        model->insertrow(model->rowcount(),itemlist);                 // 插入一行,需要每个cell的item      qmodelindex curindex=model->index(model->rowcount()-1,0);     // 创建最后一行的modelindex        selection->clearselection();                                      // 清空当前选中项      selection->setcurrentindex(curindex,qitemselectionmodel::select); // 设置当前选中项为当前选择行  }

插入代码演示效果:

C/C++中的 Qt StandardItemModel 数据模型应用解析

实现插入一行数据: 为tableview插入一行数据(在文件任意位置插入数据)

  // https://www.cnblogs.com/lyshark  void mainwindow::on_actioninsert_triggered()  {      qlist<qstandarditem*> itemlist;       // qstandarditem的列表类      qstandarditem *item;        // 模拟插入前五列数据      for(int i=0;i<fixedcolumncount-1;i++)      {          item= new qstandarditem("测试(插入行)");  // 新建一个qstandarditem          itemlist << item;                        // 添加到列表类      }        qstring str;                               // 获取表头文字      str=model->headerdata(model->columncount()-1,qt::horizontal,qt::displayrole).tostring();      item=new qstandarditem(str);      // 创建item      item->setcheckable(true);         // 设置为可使用checkbox      itemlist<<item;                   // 添加到列表类        qmodelindex curindex=selection->currentindex(); // 获取当前选中项的索引      model->insertrow(curindex.row(),itemlist);      // 在当前行的前面插入一行      selection->clearselection();                                       // 清除当前选中项      selection->setcurrentindex(curindex,qitemselectionmodel::select);  // 设置当前选中项为当前选择行  }

插入代码演示效果:

C/C++中的 Qt StandardItemModel 数据模型应用解析

实现删除一行数据: 删除数据之前需要通过selection->currentindex()确定当前选中行,并通过model->removerow()移除即可。

  // https://www.cnblogs.com/lyshark  void mainwindow::on_actiondelete_triggered()  {      qmodelindex curindex = selection->currentindex();  // 获取当前选择单元格的模型索引        // 先判断是不是最后一行      if (curindex.row()==model->rowcount()-1)      {          model->removerow(curindex.row()); //删除最后一行      }      else      {          model->removerow(curindex.row());//删除一行,并重新设置当前选择行          selection->setcurrentindex(curindex,qitemselectionmodel::select);      }  }

删除代码效果演示:

C/C++中的 Qt StandardItemModel 数据模型应用解析

实现字体数据对齐: 表格中的字体可以实现多种对其方式,对齐方式分为 居中对齐,左对齐,右对齐 三种。

  // 设置表格居中对齐  void mainwindow::on_pushbutton_clicked()  {      if (!selection->hasselection())          return;        qmodelindexlist selectedindex=selection->selectedindexes();        qmodelindex index;      qstandarditem *item;        for (int i=0; i<selectedindex.count(); i++)      {          index=selectedindex.at(i);          item=model->itemfromindex(index);          item->settextalignment(qt::alignhcenter);      }  }    // 设置表格左对齐  // https://www.cnblogs.com/lyshark  void mainwindow::on_pushbutton_2_clicked()  {      if (!selection->hasselection()) //没有选择的项          return;    //获取选择的单元格的模型索引列表,可以是多选      qmodelindexlist selectedindex=selection->selectedindexes();        for (int i=0;i<selectedindex.count();i++)      {          qmodelindex aindex=selectedindex.at(i); //获取其中的一个模型索引          qstandarditem* aitem=model->itemfromindex(aindex);//获取一个单元格的项数据对象          aitem->settextalignment(qt::alignleft);//设置文字对齐方式      }  }    // 设置表格右对齐  void mainwindow::on_pushbutton_3_clicked()  {      if (!selection->hasselection())          return;        qmodelindexlist selectedindex=selection->selectedindexes();        qmodelindex aindex;      qstandarditem *aitem;        for (int i=0;i<selectedindex.count();i++)      {          aindex=selectedindex.at(i);          aitem=model->itemfromindex(aindex);          aitem->settextalignment(qt::alignright);      }  }

对齐代码效果演示:

C/C++中的 Qt StandardItemModel 数据模型应用解析

实现字体数据加粗: 将选中行的字体进行加粗显示。

  // 设置字体加粗显示  // https://www.cnblogs.com/lyshark  void mainwindow::on_pushbutton_4_clicked()  {      if (!selection->hasselection())          return;    //获取选择单元格的模型索引列表      qmodelindexlist selectedindex=selection->selectedindexes();        for (int i=0;i<selectedindex.count();i++)      {          qmodelindex aindex=selectedindex.at(i); //获取一个模型索引          qstandarditem* aitem=model->itemfromindex(aindex);//获取项数据          qfont font=aitem->font(); //获取字体          font.setbold(true); //设置字体是否粗体          aitem->setfont(font); //重新设置字体      }

加粗代码效果演示:

C/C++中的 Qt StandardItemModel 数据模型应用解析

实现保存文件: 当保存文件被点击后触发,通过便利tablewidget模型组件中的数据,并将数据通过astream << str << "n";写出到记事本中。

  // https://www.cnblogs.com/lyshark  // 【保存文件】  void mainwindow::on_actionsave_triggered()  {      qstring curpath=qcoreapplication::applicationdirpath(); // 获取应用程序的路径        // 调用打开文件对话框选择一个文件      qstring afilename=qfiledialog::getsavefilename(this,tr("选择一个文件"),curpath,"数据文件(*.txt);;所有文件(*.*)");        if (afilename.isempty()) // 未选择文件则直接退出          return;        qfile afile(afilename);        // 以读写、覆盖原有内容方式打开文件      if (!(afile.open(qiodevice::readwrite | qiodevice::text | qiodevice::truncate)))          return;        qtextstream astream(&amp;afile);    // 用文本流读取文件      qstandarditem *item;      qstring str;      int x = 0,y = 0;        ui-&gt;plaintextedit-&gt;clear();    // 获取表头文字      for (x=0; x&lt;model-&gt;columncount(); x++)      {          item=model-&gt;horizontalheaderitem(x);     // 获取表头的项数据          str= str + item-&gt;text() + "tt";        // 以tab制表符隔开      }      astream &lt;&lt; str &lt;&lt; "n";                      // 文件里需要加入换行符n      ui-&gt;plaintextedit-&gt;appendplaintext(str);    // 获取数据区文字      for ( x=0; x &lt; model-&gt;rowcount(); x++)      {          str = "";          for( y=0; y &lt; model-&gt;columncount()-1; y++)          {              item=model-&gt;item(x,y);              str=str + item-&gt;text() + qstring::asprintf("tt");          }            // 对最后一列需要转换一下,如果判断为选中则写1否则写0          item=model-&gt;item(x,y);          if (item-&gt;checkstate()==qt::checked)              str= str + "1";          else              str= str + "0";             ui-&gt;plaintextedit-&gt;appendplaintext(str);           astream &lt;&lt; str &lt;&lt; "n";      }  }    // 【导出txt文件】:将tableview中的数据导出到plaintextedit显示  void mainwindow::on_actionview_triggered()  {          ui-&gt;plaintextedit-&gt;clear();          qstandarditem *item;          qstring str;        //获取表头文字          int x=0,y=0;          for (x=0; x&lt;model-&gt;columncount(); x++)          { //              item=model-&gt;horizontalheaderitem(x);              str= str + item-&gt;text() + "t";          }          ui-&gt;plaintextedit-&gt;appendplaintext(str);        //获取数据区的每行          for (x=0; x&lt;model-&gt;rowcount(); x++)          {              str="";              for(y=0; y&lt;model-&gt;columncount()-1; y++)              {                  item=model-&gt;item(x,y);                  str= str + item-&gt;text() + qstring::asprintf("t");              }                item=model-&gt;item(x,y);              if (item-&gt;checkstate()==qt::checked)                  str= str + "1";              else                  str= str + "0";                 ui-&gt;plaintextedit-&gt;appendplaintext(str);          }  }

文件保存后如下:

C/C++中的 Qt StandardItemModel 数据模型应用解析

到此这篇关于c/c++中的 qt standarditemmodel 数据模型应用解析的文章就介绍到这了,更多相关c++ qt standarditemmodel 数据模型内容请搜索<猴子技术宅>以前的文章或继续浏览下面的相关文章希望大家以后多多支持<猴子技术宅>!

需要了解更多c/c++开发分享C/C++中的 Qt StandardItemModel 数据模型应用解析,都可以关注C/C++技术分享栏目—猴子技术宅(www.ssfiction.com)

本文来自网络收集,不代表猴子技术宅立场,如涉及侵权请点击右边联系管理员删除。

如若转载,请注明出处:https://www.ssfiction.com/c-cyuyankaifa/967163.html

(0)
上一篇 2021年12月6日 下午6:17
下一篇 2021年12月6日 下午6:21

精彩推荐

发表评论

您的电子邮箱地址不会被公开。