二十七、Qt数据库(七)QSqlRelationalTableModel
- 格式:doc
- 大小:116.50 KB
- 文档页数:4
qt数据库操作总结整理⼀下 QT 操作数据库的⼀些要点,以备以后的查询学习(主要是操作 mysql )。
⾸先,要查询相关的驱动是否已经装好了,可以⽤以下的程序进⾏验证:#include <QtCore/QCoreApplication>#include <QSqlDatabase>#include <QDebug>#include <QStringList>int main(int argc, char *argv[]){QCoreApplication a(argc, argv);qDebug()<<"Available drivers:";QStringList drivers = QSqlDatabase::drivers();foreach(QString driver, drivers)qDebug() <<"/t" << driver;return a.exec();}结果如下:接着是连接数据库:#include <QtGui/QApplication>#include <QtGui>#include <QtSql>bool createConnection(){QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");db.setDatabaseName("test");db.setUserName("root");db.setPassword("123456");bool ok = db.open();if(!ok){QMessageBox::critical(0, QObject::tr(" 连接数据库失败 "), stError().text());return false;}else{QMessageBox::information(0, QObject::tr("Tips"), QObject::tr(" 连接数据库成功 "));}}int main(int argc, char *argv[]){QApplication a(argc, argv);QTextCodec *codec= QTextCodec::codecForName("GB2312"); QTextCodec::setCodecForLocale(codec);QTextCodec::setCodecForCStrings(codec);QTextCodec::setCodecForTr(codec);if(!createConnection())return 1;return a.exec();}结果如下:插⼊操作://ODBC 数据库表⽰⽅式QSqlQuery query;query.prepare( “insert into student (id, name) ”“values (:id, :name) ”);query.bindValue(0, 5);query.bindValue(1, “sixth ”);query.exec();//Oracle 表⽰⽅式query.prepare( “insert into student (id, name) ”“values (?, ?) ”);query.bindValue(0, 5);query.bindValue(1, “sixth ”);query.exec();// 使⽤ addBindValue() 函数,省去了编号,它是按属性顺序赋值的query.prepare( “insert into student (id, name) ”“values (?, ?) ”);query.addBindValue(5);query.addBindValue( “sixth ”);query.exec();// 使⽤ ODBC ⽅法时,可以将编号⽤实际的占位符代替query.bindValue( “:id ”, 5);query.bindValue( “:name ”, “sixth ”);query.exec();注意:最后⼀定要执⾏ exec() ,否则上⾯的语句是不会被执⾏的。
(⼗⼋)链接数据库,QSqlTableModelQMYSQL——mysqlQSQLITE——sqliteQOICQ——orcale所需头⽂件.pro增加 sql#include <QSqlDatabase>#include <QSqlError>#include <QSqlQuery>QT += core gui sqlQSqlDatabase: QMYSQL driver not loadedQSqlDatabase: available drivers: QSQLITE QMYSQL QMYSQL3 QODBC QODBC3 QPSQL QPSQL7出现以上问题,找到Mysql an'zhu安装⽬录下lib 下libmysql.dll动态库复制到 C:\Qt\5.11.2\mingw53_32\bin 下显⽰模型中的数据, 需要使⽤视图 QTableView控件 - QSqlTableModel类mysql.cpp#include "mysql.h"#include "ui_mysql.h"#include <QSqlDatabase>#include <QDebug>#include <QMessageBox>#include <QSqlError>#include <QSqlQuery>MySql::MySql(QWidget *parent) :QWidget(parent),ui(new Ui::MySql){ui->setupUi(this);// 添加⼀个mysql数据库qDebug() << QSqlDatabase::drivers();// ("QSQLITE", "QMYSQL", "QMYSQL3", "QODBC", "QODBC3", "QPSQL", "QPSQL7")QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");// 设置数据库db.setHostName("127.0.0.1"); // 主机IPdb.setUserName("root"); // 登录mysql数据库的⽤户名db.setPassword("123456"); // 登录密码db.setDatabaseName("books"); // 连接的数据库名// 打开数据库if(db.open() == false){QMessageBox::warning(this, "warning", stError().text());}// 增删查改 ...// 添加⼀条记录QSqlQuery query;QString sql = "insert into app_authors(name,age) values('vincent',100)";query.exec(sql);// 预处理// ? -- 通配符, odbc风格的通配符query.prepare("insert into app_authors(name,age) values(?,?)");// 添加绑定数据QVariantList nameList;nameList << "aa" << "bb" << "cc";query.addBindValue(nameList);QVariantList ageList;ageList << 11 << 54 << 88;query.addBindValue(ageList);// 执⾏批处理query.execBatch();// oracle 风格的通配符// 定义⽅式: :+⾃定义的名字query.prepare("insert into app_authors(name, age) values(:name, :age)");QVariantList ageList;ageList << 111 << 52 << 82;query.bindValue(":age",ageList);QVariantList nameList;nameList << "hh" << "ff" << "gg";query.bindValue(":name",nameList);query.execBatch();// 数据查询query.exec("select name, age from app_authors");while(query.next()) { // 遍历每⼀条记录qDebug() << query.value(0).toString().toUtf8().data() //// 0 -- 第⼀个字段的索引 << query.value(1).toInt()<< query.value("name").toString().toUtf8().data();}// 1. 实例化modelmodel = new QSqlTableModel(this);// 2. 将模型设置到视图中ui->tableView->setModel(model);// 3. 给model设置数据库表 -- 前提条件: 数据库已经打开了model->setTable("app_authors");// 4. 查询表model->select();// 5. 设置表头model->setHeaderData(0, Qt::Horizontal, "编号");model->setHeaderData(1,Qt::Horizontal,"姓名");model->setHeaderData(2,Qt::Horizontal,"年龄");model->setEditStrategy(QSqlTableModel::OnManualSubmit);}MySql::~MySql(){delete ui;}void MySql::on_submit_clicked(){model->submitAll();}void MySql::on_revert_clicked(){model->revertAll(); // 撤销步骤model->submitAll(); // 提交步骤 -- 更新数据模型 model->select();}void MySql::on_search_clicked(){QString name = ui->lineEdit->text();//slect * from aa where name = 'xiaoming';// 设置过滤条件QString sql = QString("name='%1'").arg(name);model->setFilter(sql);// 重新查询model->select();}mysql.h#ifndef MYSQL_H#define MYSQL_H#include <QWidget>#include <QSqlTableModel>// 数据模型// 显⽰模型中的数据, 需要使⽤视图 QTableView - QSqlTableModel// qt model - view 模型namespace Ui {class MySql;}class MySql : public QWidget{Q_OBJECTpublic:explicit MySql(QWidget *parent = 0); ~MySql();private slots:void on_submit_clicked();void on_revert_clicked();void on_search_clicked(); private:Ui::MySql *ui;QSqlTableModel * model;};#endif// MYSQL_H。
QListView,QTreeView和QStandardItemModel的简单使用//model有以下几种:// QStringListModel 存储一组字符串// QStandardItemModel 存储任意层次结构的数据// QDirModel 对文件系统进行封装// QSqlQueryModel 对SQL的查询结果集进行封装// QSqlTableModel 对SQL中的table进行封装// QSqlRelationalTableModel 对带有foreign key的SQL table进行封装// QSortFilterProxyModel 对另一个model执行sort and/or filter// model中存放的每项数据都有相应的"model index",由QModelIndex类来表示。
// 每个index由三个部分构成:row,column和表明所属model的指针。
对于一维的list model,column部分永远为0。
//下面是两个例子(此实例可适当改动),介绍了QStringListModel,QStandardItemModel,QDirModel用QTreeView和QListView来显示的例子//建一个cpp文件拷贝以下代码即可#include <QApplication>#include <QWidget>#include<QTreeView>#include<QDirModel>#include<QHBoxLayout>#include<QSplitter>#include<QStringListModel>#include<QListView>#include<QStandardItemModel>int main(int argc, char *argv[]) {/*QApplication app(argc, argv);//以下是QStandardItemModel的简单使用,只需替换view的model为qstmodel就可以看到效果QStandardItemModel *qstmodel=new QStandardItemModel();QStandardItem* item1 = newQStandardItem("item1");QStandardItem* item2 = newQStandardItem("item2");QStandardItem* item3 = newQStandardItem("item3");item1->appendRow(item2);qstmodel->appendRow(item1);qstmodel->appendRow(item3);//以下是StringListModel的示例,只需替换view的model为mod就可以看到效果,QListView也适用QStringList names;names<<"a"<<"b";QAbstractItemModel *mod=newQStringListModel(names);//要注意的是,这里把StringListModel作为一个QAbstractItemModel来使用。
QSqlTableModel类继承至QSqlQueryModel类,该类提供了一个可读写单张SQL表的可编辑数据模型,功能:修改,插入,删除,查询,和排序常用函数QVariantheaderData ( intsection,QtOrientationorientation, introle= QtDisplayRole ) const 获取水平头或垂直头标题bool setHeaderData ( intsection,QtOrientationorientation, constQVariant&value, introle= QtEditRole ) 设置水平头或垂直头标题int rowCount ( constQModelIndex&parent= QModelIndex() ) const 返回行数int columnCount ( constQModelIndex&index= QModelIndex() ) const 返回列数virtual bool removeColumns ( int column, int count, const QModelIndex & parent = QModelIndex() ) model-removeColumns (0)删除第一列bool QSqlTableModelsubmitAll (),提交所有被修改的数据,然后修改的数据被保存在数据库中void QSqlTableModelrevertAll () 撤销所有的修改,如果数据库已经被提交了修改,就不能通过撤销修改改回来了virtual void revertRow ( int row ) 恢复指定行的改变void QSqlTableModelsetFilter ( const QString & filter ) 筛选,按照字符串filter对数据库进行筛选,相当于SQL中的WHERE语句bool QSqlTableModelselect () 在筛选和排序的条件下,将数据库中符合要求的在mode表格中显示出来void QSqlTableModelsetSort ( int column, QtSortOrder order ) 排序操作。
1.QSqlQueryModel *model = new QSqlQueryModel();2.model->setQuery("SELECT table_er_id, table_group.group_name FROMtable_group,"3."table_user WHERE table_group.group_id=table_user.group_id");4.5.for(int i = 0; i < model->rowCount(); i++)6.{7.qDebug() << model->record(i).value("user_id").toString();8.qDebug() << model->record(i).value("group_name").toString();9.}1.sqlite3可以有多种多表查询方法,比如 select (select * from table2) from table1where xxx=xxx;1.select table1.abc from table1,table2 where table1.xxx=table2.xxx;1.select table1.abc from table1 inner join table2 on table1.xxx=table2.xxx;1.QSqlTableModel tablemodel; //单表查询2.tablemodel.setTable("table_user"); //绑定表3.tablemodel.setFilter("group_id=1"); //设置查询条件4.tablemodel.select(); //查询5.for(int i = 0; i < tablemodel.rowCount(); i++)6.{7.qDebug() << tablemodel.record(i).value(1).toString();8.}1.int UserID_Index = tablemodel.record().indexOf("user_id");2.qDebug() << tablemodel.record(i).value(UserID_Index).toString();1.tablemodel.record(i).value("user_id").toString();1.QSqlRelationalTableModel *model = new QSqlRelationalTableModel();2.model->setTable("table_user");3.model->setRelation(1, QSqlRelation("table_group", "group_id","group_id")); //表明table_group.group_id是table_group的主键4.model->setHeaderData(0, Qt::Horizontal, tr("工号"));5.model->setHeaderData(1, Qt::Horizontal, tr("组别"));6.7.if(!model->select())8.{9.QMessageBox::critical(this, tr("错误提示"), model->lastError().text(),QMessageBox::Cancel);10.}。
qt数据库的用法
Qt是一种流行的跨平台桌面应用程序开发框架,它提供了一个灵活的数据库模块,用于连接和管理不同类型的数据库。
Qt数据库模块支持多种数据库,包括MySQL、PostgreSQL、SQLite、Oracle和Microsoft SQL Server等。
Qt数据库模块的使用需要懂得数据库编程的知识,包括连接到数据库、执行SQL查询、处理结果集等。
在Qt中,我们可以使用QSqlDatabase类来建立和管理数据库连接,使用QSqlQuery类来执行查询操作,并且可以使用QSqlTableModel、QSqlRelationalTableModel和QSqlQueryModel类来管理结果集。
Qt数据库模块提供了一个灵活的API,可以通过编写C++代码来执行数据库操作。
编写高质量的数据库程序需要考虑数据库安全、性能和可靠性等方面的问题。
因此,在使用Qt数据库模块时,需要注意正确处理数据库连接、避免SQL注入攻击、优化查询性能、处理事务和异常等。
总之,Qt数据库模块是一个非常强大的工具,可以帮助开发人员在跨平台应用程序中轻松地集成数据库功能。
如果您是Qt开发人员,那么学习和掌握Qt数据库模块的用法是非常必要的。
- 1 -。
当然我们一定要记住这个顺序,先创建数据库,然后再去创建一个表(作为菜鸟的我犯这个错误了),还有一点需要注意的红色标记的那句话,我参考的数籍一般都这样写db.setDatabaseName(":memory:");这样就把生成的数据库文件是在内存当中的,在工程文件目录下找不到。
上面使我们创建了一个数据库和一个表,那么我们如何把它呈现在我们的QTableview部件上呢?QSqlTableModel *model = new QSqlTableModel;model->setTable("person");model->setEditStrategy(QSqlTableModel::OnManualSubmit);model->select();ui->tableView->setModel(model);ui->tableView->show();上面的代码就把数据库中的信息不加筛选的打印到控件上了。
第一次写博客大家多多包涵。
Qt中提高sqlite的读写速度SQLite数据库本质上来讲就是一个磁盘上的文件,所以一切的数据库操作其实都会转化为对文件的操作,而频繁的文件操作将会是一个很好时的过程,会极大地影响数据库存取的速度。
例如:向数据库中插入100万条数据,在默认的情况下如果仅仅是执行query.exec("insert into DataBase(......)values(......)");就会打开和关闭文件100万次,所以速度当然会很慢。
SQLite 数据库是支持事务操作的,于是我们就可以通过事务来提高数据库的读写速度。
事务的基本原理是:数据库管理系统首先会把要执行的sql语句存储到内存当中,只有当commit()的时候才一次性全部执行所有内存中的数据库。
下面是一个简单的QT sqlite数据库事务的例子:#include <QtCore/QCoreApplication>#include <QtSql>#include <iostream>using namespace std;int main(int argc, char *argv[]){QCoreApplication a(argc, argv);QSqlDatabase db_sqlite = QSqlDatabase::addDatabase("QSQLITE", "connSQLite");db_sqlite.setDatabaseName("SQLiteDB.db3");db_sqlite.open();QSqlQuery query("", db_sqlite);bool bsuccess = false;QTime tmpTime;// 开始启动事务db_sqlite.transaction();tmpTime.start();for(int i = 0; i<100000; i++){bsuccess = query.exec("insert into DataBase(D_1,D_2,D_3,D_4,D_5) values('TT','TT','TT','TT','TT')");if (!bsuccess){cout<<"Error occur"<<endl;break;}}// 提交事务,这个时候才是真正打开文件执行SQL语句的时候db_mit();cout<<"10000条数据耗时:"<<tmpTime.elapsed()<<"ms"<<endl;}其实QT 操作sqlite数据库增加事务的功能就是上面例子中蓝色字体标出的两句话,如果去掉这两句话,程序又会还原为:打开文件——执行query.exec(...)——关闭文件。
qsqltablemode的index方法### QsqlTableModel的index方法解析在Qt框架中,`QsqlTableModel`是一个非常有用的类,它为SQL数据库提供了一个可编辑的数据模型。
这个模型是`QAbstractTableModel`的子类,因此它继承了丰富的接口和便捷的操作方法。
本文将深入探讨`QsqlTableModel`类中的`index`方法,解释其功能、使用场景和实现细节。
#### 功能概述`index`方法通常用于获取模型中项的索引位置。
在`QsqlTableModel`的上下文中,这个方法允许开发者在知道行和列的情况下快速定位数据项。
#### 方法原型以下是`QsqlTableModel`中`index`方法的原型:```cppQModelIndex QsqlTableModel::index(int row, int column, const QModelIndex &parent = QModelIndex()) const;```参数说明:- `row`: 要定位的行的编号。
- `column`: 要定位的列的编号。
- `parent`: 索引的父级。
在`QsqlTableModel`中,如果模型是层级化的,这个参数指定了索引的父索引。
在大多数情况下,可以传递默认的`QModelIndex()`。
#### 使用场景当你需要执行以下操作时,会用到`index`方法:1.定位数据以便于读取或修改。
2.实现自定义的模型视图迭代逻辑。
3.检索行的特定数据,如行号或列值。
#### 示例代码以下是如何在`QsqlTableModel`中使用`index`方法的一个简单示例:```cppQsqlTableModel *model = new QsqlTableModel(this);model->setTable("my_table");model->select();// 获取第2行,第3列的索引QModelIndex index = model->index(1, 2);// 通过索引读取数据QVariant data = model->data(index);```在这个例子中,我们从名为"my_table"的数据库表中选择了数据,并获取了第二行第三列的数据。
Qt--⾃定义Model众所周知,Qt提供了⼀套Model/View框架供开发者使⽤,Model⽤来提供数据, View则⽤来提供视觉层的显⽰。
实际上这是⼀套遵循MVC设计模式的GUI框架,因为Qt还提供了默认的Delegate作为Controller来作为控制器。
MVC的好处这⾥就不多说了,为了开发者使⽤⽅便,Qt还提供了基于项(Item)的Model/View实现----QXxxWidget(QTableWidget、QListWidget等),对于⼀些简单的应⽤场景,这已经⾜够了并且使⽤起来⾮常⽅便。
这⾥我们简单介绍下如何使⽤⾃定义的数据模型,来满⾜各种花式的要求。
1. 选择合适的Model继承1.1 标准数据模型Qt实现了4类标准数据模型供我们在不同的场景下使⽤:1. QStringListModel:存储字符串列表。
2. QStandardItemModel:存储树状结构的任意数据。
3. QFileSystemModel:存储本地⽂件系统上的⽂件和⽬录信息。
4. QSqlQueryModel、QSqlRelationalTableModel、QSqlTableModel:存储关系型数据库中的数据。
如果使⽤情况和上述情况之⼀⽐较相似,则可以考虑继承对应的模型类,并重新实现少数虚函数。
1.2 抽象数据模型抽象数据模型有3类:1. QAbstractItemModel:项模型,这是所有数据模型的基类。
2. QAbstractListModel:列表模型,结合QListView使⽤最合适。
3. QAbstractTableModel:表模型,结合QTableView使⽤最合适。
2. 继承抽象模型Qt官⽅提供了完善的来帮助开发者来⾃定义模型类。
根据官⽹,⼦类化模型需要开发者实现的功能(即需要重新实现的虚函数)按功能来分可以分为三类:项数据处理:这⼜可以分为三类----只读访问、可编辑、调整⼤⼩。
二十一、Qt数据库(一)简介(原创)2010-03-02 12:03声明:本文原创于yafeilinux的百度博客,/yafeilinux 转载请注明出处。
从今天开始我们学习Qt数据库编程的内容。
先说明:我们以后使用现在最新的基于Qt 4.6.2的Qt Creator 1.3.1 Windows 版本,该版本是2010年2月17日发布的。
数据库几乎是每个较大的软件所必须应用的,而在Qt中也使用QtSql模块实现了对数据库的完美支持。
我们在Qt Creator的帮助中查找QtSql Module,其内容如下图:可以看到这个模块是一组类的集合,使用这个模块我们需要加入头文件#include <QtSql>,而在工程文件中需要加入一行代码:QT += sql这里每个类的作用在后面都有简单的介绍,你也可以进入其中查看其详细内容。
下面我们先简单的说一下QSqlDatabase类和QSqlQuery类。
QSqlDatabase类实现了数据库连接的操作,现在Qt支持的数据库类型有如下几种:而现在我们使用的免费的Qt只提供了SQLite和ODBC数据库的驱动(我们可以在Qt Creator安装目录下的qt\plugins\sqldrivers文件夹下查看),而其他数据库的驱动需要我们自己添加。
SQLite是一个小巧的嵌入式数据库,关于它的介绍你可以自己在网上查找。
QSqlQuery类用来执行SQL语句。
(关于SQL语句:在我的教程中只会出现很简单的SQL语句,你没有相关知识也可以看懂,但是如果想进行深入学习,就需要自己学习相关知识了。
)下面我们就先利用这两个类来实现最简单的数据库程序,其他的类我们会在以后的教程中逐个学习到。
1.新建Qt控制台工程。
2.选择上QtSql模块,这样就会自动往工程文件中添加QT += sql 这行代码了。
3.修改main.cpp中的内容如下。
#include <QtCore/QCoreApplication>#include <QtSql>int main(int argc, char *argv[]){QCoreApplication a(argc, argv);QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); //添加数据库驱动db.setDatabaseName(":memory:"); //数据库连接命名if(!db.open()) //打开数据库{return false;}QSqlQuery query; //以下执行相关QSL语句query.exec("create table student(id int primary key,name varchar)");//新建student表,id设置为主键,还有一个name项query.exec("insert into student values(1,'xiaogang')");query.exec("insert into student values(2,'xiaoming')");query.exec("insert into student values(3,'xiaohong')");//向表中插入3条记录query.exec("select id,name from student where id >= 2");//查找表中id >=2 的记录的id项和name项的值while(query.next()) //query.next()指向查找到的第一条记录,然后每次后移一条记录{int ele0 = query.value(0).toInt(); //query.value(0)是id的值,将其转换为int型QString ele1 =query.value(1).toString();qDebug() << ele0 <<ele1 ; //输出两个值}return a.exec();}我们使用了SQLite数据库,连接名为“:memory:”表示这是建立在内存中的数据库,也就是说该数据库只在程序运行期间有效。
讲完QSqlTableModel了,我们这次讲这个类的扩展类QSqlRelationalTableModel,它们没有太大的不同,唯一的就是后者在前者的基础之上添加了外键(或者叫外码)的支持。
QSqlRelationalTableModel,该类为单张的数据库表提供了一个可编辑的数据模型,它支持外键。
我们还是新建Qt4 Gui Application工程,我这里工程名为relationalTableModel ,然后选中QtSql模块,Base class选QWidget。
工程建好后,添加C++ Header File ,命名为database.h,更改其内容如下:
#ifndef DATABASE_H
#define DATABASE_H
#include <QSqlDatabase>
#include <QSqlQuery>
static bool createConnection()
{
QSqlDatabase db = QSqlDatabase::addDatabase(“QSQLITE”);
db.setDatabaseName(“database.db”);
if(!db.open()) return false;
QSqlQuery query;
query.exec(“create table student (id int primary key, name vchar,course int)”);
query.exec(“insert into student values (1,’yafei0′,1)”);
query.exec(“insert into student values (2,’yafei1′,1)”);
query.exec(“insert into student values (3,’yafei2′,2)”);
query.exec(“create table course (id int primary key, name vchar, teacher vchar)”);
query.exec(“insert into course values (1,’Math’,'yafeilinux1′)”); query.exec(“insert into course values (2,’
English’,'yafeilinux2′)”);
query.exec(“insert into course values (3,’
Computer’,'yafeilinux3′)”);
return true;
}
#endif // DATABASE_H
我们在这里建立了两个表,student表中有一项是course,它是int型的,而course表的主键也是int型的。
如果要将course项和course表进行关联,它们的类型就必须相同,一定要注意这一点。
然后将main.cpp中的内容更改如下:
#include <QtGui/QApplication>
#include “widget.h”
#include “database.h”
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
if(!createConnection()) return 1;
Widget w;
w.show();
return a.exec();
}
我们在widget.h中添加头文件: #include <QSqlRelationalTableModel>
然后在private中声明对象:QSqlRelationalTableModel *model;
我们在widget.ui中添加一个Table View部件到窗体上,然后到widget.cpp
中的构造函数里添加如下代码:
model = new QSqlRelationalTableModel(this);
model->setEditStrategy(QSqlTableModel::OnFieldChange); //属性变化时写入数据库
model->setTable(“student”);
model->setRelation(2,QSqlRelation(“course”,”id”,”name”));
//将student表的第三个属性设为course表的id属性的外键,并将其显示为course表的name属性的值
model->setHeaderData(0, Qt::Horizontal, QObject::tr(“ID”));
model->setHeaderData(1, Qt::Horizontal, QObject::tr(“Name”)); model->setHeaderData(2, Qt::Horizontal, QObject::tr(“Course”)); model->select();
ui->tableView->setModel(model);
我们修改了model的提交策略,OnFieldChange表示只要属性被改动就马上写入数据库,这样就不需要我们再执行提交函数了。
setRelation()函数实现了创建外键,注意它的格式就行了。
运行效果如下:
可以看到Course属性已经不再是编号,而是具体的课程了。
关于外键,你也应该有一定的认识了吧,说简单点就是将两个相关的表建立一个桥梁,让它们关联起来。
那么我们也希望,如果用户更改课程属性,那么他只能在课程表中有的课程中进行选择,而不能随意填写课程。
在Qt中的QSqlRelationalDelegate委托类就能实现这个功能。
我们只需在上面的构造函数的最后添加一行代码:
ui->tableView->setItemDelegate(new
QSqlRelationalDelegate(ui->tableView));
添加代理(委托),在我这里不知为什么会出现SqlRelationalDelegate is not a type name的提示,不过可以编译通过。
我们需要在widget.cpp中添加头文件:#include <QSqlRelationalDelegate>
运行效果如下:
可以看到这时修改Course属性时,就会出现一个下拉框,只能选择course表中的几个值。
而利用这个类来操作数据库,与前面讲到的QSqlTableModel没有区别,这里就不再重复。
这几篇文章一共讲了好几种操作数据库的方法,到底应该使用哪个呢?那就看你的需求了,根据这几种方法的特点进行选择吧。
分类:Qt系列教程作者: yafeilinux 日期:四月 30th, 2010. 244 views Tags: creator, qt, yafeilinux, 教程, 数据库
2 条评论在“二十七、Qt数据库(七)QSqlRelationalTableModel”
1.ding404说:
2010年05月26日于9:27 上午
学习完毕n(0_0)n, 谢谢楼主。
针对lanyu的问题,可能是由于你的代码
是复制网页上的,这样可能student name 或者course name的单引号格
式有问题,需要手动改回来,否则编译能通过,但是运行的时候表格里啥
都不显示。
我也是找了很久才发现这个问题,编译不会有错的。
nyu说:
2010年05月17日于11:58 下午
请问,为什么我的运行结果里显示不出表格里的内容,只有个表格?加入
ui->tableView->setItemDelegate(new
QSqlRelationalDelegate(ui->tableView));和#include 后,出现
error: expected type-specifier before ‘QSqlRelationDelegate’
谢谢啦!。