Qt5 學習參考資料之--QSqlRelationalTableModel
源部落格位置:http://www.qter.org/portal.php?mod=view&aid=58
導語
QSqlRelationalTableModel繼承自QSqlTableModel,並且對其進行了擴充套件,提供了對外來鍵的支援。一個外來鍵就是一個表中的一個欄位和其他表中的主鍵欄位之間的一對一的對映。例如,student表中的course欄位對應的是course表中的id欄位,那麼就稱欄位course是一個外來鍵。因為這裡的course欄位的值是一些數字,這樣的顯示很不友好,使用關係表格模型,就可以將它顯示為course表中的name欄位的值。
環境:Windows 7 + Qt 5.8.0(包含QtCreator 4.2.1)
正文
一、使用外來鍵
1.新建Qt Widgets應用,名稱為relationaltablemodel,基類為QMainWindow類名為MainWindow保持不變。完成後開啟relationaltablemodel.pro專案檔案,將第一行改為:
- QT += core gui sql
複製程式碼
然後儲存該檔案。
2.下面向專案中新增新的C++標頭檔案connection.h,並更改其內容如下:
- #ifndef CONNECTION_H
- #define CONNECTION_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 primarykey, 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 // CONNECTION_H
複製程式碼
在這裡建立了兩個表,student表中有一欄位是course,它是int型的,而course表的主鍵也是int型的。如果要將course欄位和course表進行關聯,它們的型別就必須相同,一定要注意這一點。
3.更改main.cpp檔案內容如下:
- #include "mainwindow.h"
- #include <QApplication>
- #include "connection.h"
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- if(!createConnection()) return 1;
- MainWindow w;
- w.show();
- return a.exec();
- }
複製程式碼
4.然後到mainwindow.h檔案中,先包含標頭檔案:
- #include<QSqlRelationalTableModel>
複製程式碼
然後新增private型別物件定義:
- QSqlRelationalTableModel *model;
複製程式碼
5.到設計模式,往介面上拖放一個Table View部件。
6.到mainwindow.cpp檔案中,在建構函式裡新增如下程式碼:
- model = new QSqlRelationalTableModel(this);
- //欄位變化時寫入資料庫
- model->setEditStrategy(QSqlTableModel::OnFieldChange);
- model->setTable("student");
- //將student表的第三個欄位設為course表的id欄位的外來鍵,
- //並將其顯示為course表的name欄位的值
- model->setRelation(2,QSqlRelation("course","id","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()函式實現了建立外來鍵,注意它的格式就行了。
7.執行程式,效果如下圖所示。
可以看到Course欄位已經不再是編號,而是具體的課程名稱了。關於外來鍵,大家也應該有一定的認識了吧,說簡單點就是將兩個相關的表建立一個橋樑,讓它們關聯起來。
二、使用委託
有時我們也希望,如果使用者更改課程欄位,那麼只能在課程表中已有的課程中進行選擇,而不能隨意填寫課程。Qt中還提供了一個QSqlRelationalDelegate委託類,它可以為QSqlRelationalTableModel顯示和編輯資料。這個委託為一個外來鍵提供了一個QComboBox部件來顯示所有可選的資料,這樣就顯得更加人性化了。使用這個委託很簡單,我們先在mainwindow.cpp檔案中新增標頭檔案:
- #include <QSqlRelationalDelegate>
複製程式碼
然後繼續在建構函式中新增如下一行程式碼:
- ui->tableView->setItemDelegate(new QSqlRelationalDelegate(ui->tableView));
複製程式碼
執行程式,效果如下圖所示。
結語
我們可以根據自己的需要來選擇使用哪個模型。如果熟悉SQL語法,又不需要將所有的資料都顯示出來,那麼只需要使用QSqlQuery就可以了。對於QSqlTableModel,它主要是用來顯示一個單獨的表格,而QSqlQueryModel可以用來顯示任意一個結果集,如果想顯示任意一個結果集,而且想使其可讀寫,那麼建議子類化QSqlQueryModel,然後重新實現flags()和setData()函式。