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沒有區別,這里就不再重復。這幾篇文章一共講了好幾種操作數據庫的方法,到底應該使用哪個呢?那就看你的需求了,根據這幾種方法的特點進行選擇吧。