SqlTableModel组件可以将数据库中的特定字段动态显示在TableView表格组件中,通常设置QSqlTableModel类的变量作为数据模型后就可以显示数据表内容,界面组件中则通过QDataWidgetMapper类实例设置为与某个数据库字段相关联,则可以实现自动显示字段的内容,不仅是显示,其还支持动态增删改查等各种复杂操作,期间不需要使用任何SQL语句。 首先绘制好UI界面,本次案例界面稍显复杂,左侧是一个TableView组件,其他地方均为LineEdit组件与Button组件。 先来生成数据库表记录,此处我们只需要增加一个Student学生表,并插入两条测试数据即可,运行以下代码完成数据创建。includeiostreamincludeQSqlDatabaseincludeQSqlErrorincludeQSqlQueryincludeQSqlRecordincludeQtSqlincludeQDataWidgetMapperQSqlDatabaseDB;数据库连接voidMainWindow::InitSQL(){QSqlDatabasedbQSqlDatabase::addDatabase(QSQLITE);db。setDatabaseName(。lyshark。db);if(!db。open()){}执行SQL创建表https:Www。cnbloGs。comlysharkdb。exec(DROPTABLEStudent);db。exec(CREATETABLEStudent(idINTEGERPRIMARYKEYAUTOINCREMENT,nameVARCHAR(40)NOTNULL,sexVARCHAR(40)NOTNULL,ageINTEGERNOTNULL,mobileVARCHAR(40)NOTNULL,cityVARCHAR(40)NOTNULL));逐条插入数据db。exec(INSERTINTOStudent(name,sex,age,mobile,city)VALUES(lyshark。cnblogs。com,m,25,1234567890,beijing));db。exec(INSERTINTOStudent(name,sex,age,mobile,city)VALUES(www。lyshark。com,x,22,4567890987,shanghai));db。commit();db。close();} 数据库创建后表内记录如下: 【领QT开发教程学习资料,点击下方链接莬费领取,先码住不迷路】 链接 程序运行后我们将在MainWindow::MainWindow(QWidgetparent)构造函数内完成数据库表记录与TableView组件字段的对应关系绑定,将数据库绑定到QDataWidgetMapper对象上,绑定代码如下。MainWindow::MainWindow(QWidgetparent):QMainWindow(parent),ui(newUi::MainWindow){uisetupUi(this);打开数据库DBQSqlDatabase::addDatabase(QSQLITE);添加SQLLITE数据库驱动DB。setDatabaseName(。lyshark。db);设置数据库名称if(!DB。open()){}打开数据表tabModelnewQSqlTableModel(this,DB);数据表tabModelsetTable(Student);设置数据表tabModelsetEditStrategy(QSqlTableModel::OnManualSubmit);数据保存方式,OnManualSubmit,OnRowChangetabModelsetSort(tabModelfieldIndex(id),Qt::AscendingOrder);排序if(!(tabModelselect()))查询数据{}设置字段名称tabModelsetHeaderData(tabModelfieldIndex(id),Qt::Horizontal,Uid);tabModelsetHeaderData(tabModelfieldIndex(name),Qt::Horizontal,Uname);tabModelsetHeaderData(tabModelfieldIndex(sex),Qt::Horizontal,Usex);tabModelsetHeaderData(tabModelfieldIndex(age),Qt::Horizontal,Uage);tabModelsetHeaderData(tabModelfieldIndex(mobile),Qt::Horizontal,Umobile);tabModelsetHeaderData(tabModelfieldIndex(city),Qt::Horizontal,Ucity);theSelectionnewQItemSelectionModel(tabModel);关联选择模型uitableViewsetModel(tabModel);设置数据模型uitableViewsetSelectionModel(theSelection);设置选择模型uitableViewsetSelectionBehavior(QAbstractItemView::SelectRows);行选择模式添加数据映射,将选中字段映射到指定编辑框中https:www。cnblogs。comlysharKdataMappernewQDataWidgetMapper();dataMappersetModel(tabModel);dataMappersetSubmitPolicy(QDataWidgetMapper::AutoSubmit);dataMapperaddMapping(uilineEditname,tabModelfieldIndex(name));设置映射字段dataMapperaddMapping(uilineEditmobile,tabModelfieldIndex(mobile));第二个映射字段dataMappertoFirst();默认选中首条映射记录绑定信号,当鼠标选择时,在底部编辑框中输出connect(theSelection,SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),this,SLOT(oncurrentRowChanged(QModelIndex,QModelIndex)));getFieldNames();}MainWindow::MainWindow(){} 绑定成功后运行程序即可看到如下效果,数据库中的记录被映射到了组件内。 当用户点击TableView组件内的某一行记录时,则触发MainWindow::oncurrentRowChanged函数。执行获取namemobile字段,并放入映射数据集中的lineEdit编辑框中voidMainWindow::oncurrentRowChanged(constQModelIndext,constQModelIndexprevious){QUNUSED(previous);dataMappersetCurrentIndex(current。row());更细数据映射的行号intcurRecNocurrent。row();获取行号QSqlRecordcurRectabModelrecord(curRecNo);获取当前记录QStringunamecurRec。value(name)。toString();取出数据QStringmobilecurRec。value(mobile)。toString();uilineEditnamesetText(uname);设置到编辑框uilineEditmobilesetText(mobile);} 运行效果如下: 增加插入与删除记录实现方法都是调用TabModel提供的默认函数,通过获取当前选中行号,并对该行号执行增删改查方法即可。新增一条记录https:www。cnblogS。comlysharkvoidMainWindow::onpushButtonaddclicked(){tabModelinsertRow(tabModelrowCount(),QModelIndex());在末尾添加一个记录QModelIndexcurIndextabModelindex(tabModelrowCount()1,1);创建最后一行的ModelIndextheSelectionclearSelection();清空选择项theSelectionsetCurrentIndex(curIndex,QItemSelectionModel::Select);设置刚插入的行为当前选择行intcurrowcurIndex。row();获得当前行tabModelsetData(tabModelindex(currow,0),1000tabModelrowCount());自动生成编号tabModelsetData(tabModelindex(currow,2),M);默认为男tabModelsetData(tabModelindex(currow,3),0);默认年龄0}插入一条记录voidMainWindow::onpushButtoninsertclicked(){QModelIndexcurIndexuitableViewcurrentIndex();intcurrowcurIndex。row();获得当前行tabModelinsertRow(curIndex。row(),QModelIndex());tabModelsetData(tabModelindex(currow,0),1000tabModelrowCount());自动生成编号theSelectionclearSelection();清除已有选择theSelectionsetCurrentIndex(curIndex,QItemSelectionModel::Select);}删除一条记录voidMainWindow::onpushButtondeleteclicked(){QModelIndexcurIndextheSelectioncurrentIndex();获取当前选择单元格的模型索引tabModelremoveRow(curIndex。row());删除最后一行}保存修改数据voidMainWindow::onpushButtonsaveclicked(){boolrestabModelsubmitAll();if(!res){std::coutsaveasokstd::}}恢复原始状态voidMainWindow::onpushButtonresetclicked(){tabModelrevertAll();} 增删改查实现如下: 【领QT开发教程学习资料,点击下方链接莬费领取,先码住不迷路】 链接 针对与排序与过滤的实现方式如下,同样是调用了标准函数。以Combox中的字段对目标升序排列voidMainWindow::onpushButtonascendingclicked(){tabModelsetSort(uicomboBoxcurrentIndex(),Qt::AscendingOrder);tabModelselect();}以Combox中的字段对目标降序排列https:www。Cnblogs。comLySharkvoidMainWindow::onpushButtondescendingclicked(){tabModelsetSort(uicomboBoxcurrentIndex(),Qt::DescendingOrder);tabModelselect();}过滤出所有男记录voidMainWindow::onpushButtonfiltermanclicked(){tabModelsetFilter(sexM);}恢复默认过滤器voidMainWindow::onpushButtondefaultclicked(){tabModelsetFilter();} 过滤效果如下所示: 批量修改某个字段,其实现原理是首先通过irowCount()获取记录总行数,然后通过aRec。setValue设置指定字段数值,并最终tabModelsubmitAll()提交到表格中。voidMainWindow::onpushButtonclicked(){if(tabModelrowCount()0)for(inti0;itabModelrowCount();i){QSqlRecordaRectabModelrecord(i);获取当前记录aRec。setValue(age,uilineEdittext());设置数据tabModelsetRecord(i,aRec);}tabModelsubmitAll();提交修改} 循环修改实现效果如下: 上方代码中,如果需要修改或增加特定行或记录我们只需要点击相应的按钮,并在选中行直接编辑即可实现向数据库中插入数据,而有时我们不希望通过在原表上操作,而是通过新建窗体并在窗体中完成增删改,此时就需要使用Dialog窗体并配合原生SQL语句来实现对记录的操作了。 以增加为例,主窗体中直接弹出增加选项卡,并填写相关参数,直接提交即可。https:www。cnblogs。comLySharkvoidMainWindow::onpushButtoninsertclicked(){QSqlQquery。exec(selectfromStudentwhereid1);查询字段信息,是否存在QSqlRecordcurRecquery。record();获取当前记录,实际为空记录curRec。setValue(id,qryModelrowCount()1001);DialogWindowPtrnewDialog(this);Qt::WindowFlagsflagsWindowPtrwindowFlags();WindowPtrsetWindowFlags(flagsQt::MSWindowsFixedSizeDialogHint);设置对话框固定大小WindowPtrsetInsertRecord(curRec);插入记录intretWindowPtrexec();以模态方式显示对话框if(retQDialog::Accepted)OK键被按下{QSqlRecordrecDataWindowPtrgetRecordData();query。prepare(INSERTINTOStudent(id,name,sex,age,mobile,city)VALUES(:Id,:Name,:Sex,:Age,:Mobile,:City));query。bindValue(:Id,recData。value(id));query。bindValue(:Name,recData。value(name));query。bindValue(:Sex,recData。value(sex));query。bindValue(:Age,recData。value(age));query。bindValue(:Mobile,recData。value(mobile));query。bindValue(:City,recData。value(city));if(query。exec()){QStringsqlStrqryModelquery()。executedQuery();执行过的SELECT语句qryModelsetQuery(sqlStr);重新查询数据}}deleteWindowP} Dialog增加效果如下: 文章作者:lyshark(王瑞) 文章出处:https:www。cnblogs。comLySharkp15665737。html