[Qt教程] 第25篇 数据库(五)SQL表格模型QSqlTableModel
生活随笔
收集整理的這篇文章主要介紹了
[Qt教程] 第25篇 数据库(五)SQL表格模型QSqlTableModel
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
[Qt教程]?第25篇 數據庫(五)SQL表格模型QSqlTableModel
??|?查看: 923|?回復: 7| SQL表格模型QSqlTableModel 版權聲明 該文章原創于作者yafeilinux,轉載請注明出處! 導語 在上一篇我們講到只讀的QsqlQueryModel模型其實也可以實現編輯功能的,但是實現起來很麻煩。而QSqlTableModel提供了一個一次只能操作單個SQL表的讀寫模型,它是QSqlQuery的更高層次的替代品,可以瀏覽和修改獨立的SQL表,并且只需編寫很少的代碼,而且不需要了解SQL語法。 環境:Windows Xp + Qt 4.8.4+QtCreator 2.6.2 目錄 一、創建數據庫 二、修改操作 三、查詢操作 四、排序操作 五、刪除操作 六、插入操作 正文 一、創建數據庫 1.新建Qt Gui應用,項目名稱為tableModel,基類QMainWindow,類名MainWindow。 2.完成后打開tableModel.pro文件,將第一行代碼更改為: QT? ?? ??+= coregui sql 然后保存文件。 3.向項目中添加新的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(QString( ? ?? ?"create tablestudent (id int primary key, name vchar)")); ? ??query.exec(QString("insert into student values (0,'劉明')")); ? ??query.exec(QString("insert into student values (1,'陳剛')")); ? ??query.exec(QString("insert into student values (2,'王紅')")); ? ??return?true; } #endif?// CONNECTION_H 這里因為語句中使用了中文,所以使用了QString()進行編碼轉換,這個還需要在main()函數中設置編碼。 4.下面將main.cpp文件更改如下: #include?"mainwindow.h" #include?<QApplication> #include?"connection.h" #include?<QTextCodec> int?main(int?argc,?char?*argv[]) { ? ??QApplication?a(argc,?argv); ? ??QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8")); ? ??QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale()); ? ??if(!createConnection()) ? ?? ??return?1; ? ??MainWindow?w; ? ??w.show(); ? ? ? ??return?a.exec(); } ? ??這里的setCodecForCStrings()就是用來設置字符串編碼的。 5.下面進入設計模式,向窗口上拖入Label、Push Button、Line Edit和Table View等部件,進行界面設計,效果如下圖所示。 6.完成后到mainwindow.h文件中,先包含頭文件: #include?<QSqlTableModel> 然后添加私有對象聲明: QSqlTableModel?*model; 7.到mainwindow.cpp,在構造函數添加如下代碼: model?=?new?QSqlTableModel(this); model->setTable("student"); model->setEditStrategy(QSqlTableModel::OnManualSubmit); model->select();?//選取整個表的所有行 //不顯示name屬性列,如果這時添加記錄,則該屬性的值添加不上 // model->removeColumn(1); ui->tableView->setModel(model); //使其不可編輯 //ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); 這里創建一個QSqlTableModel后,只需使用setTable()來為其指定數據庫表,然后使用select()函數進行查詢,調用這兩個函數就等價于執行了“select * from student”這個SQL語句。這里還可以使用setFilter()來指定查詢時的條件,在后面會看到這個函數的使用。在使用該模型以前,一般還要設置其編輯策略,它由QSqlTableModel::EditStrategy枚舉變量定義,一共有三個值,如下圖所示。用來說明當數據庫中的值被編輯后,什么情況下提交修改。 運行程序,效果如下圖所示。 可以看到,這個模型已經完全脫離了SQL語句,我們只需要執行select()函數就能查詢整張表。上面有兩行代碼被注釋掉了,你可以取消注釋,測試一下它們的作用。 二、修改操作 1.我們進入“提交修改”按鈕的單擊信號槽,更改如下: void?MainWindow::on_pushButton_3_clicked() { ? ??model->database().transaction();?//開始事務操作 ? ??if?(model->submitAll())?{ ? ?? ??model->database().commit();?//提交 ? ??}?else?{ ? ?? ??model->database().rollback();?//回滾 ? ?? ??QMessageBox::warning(this,?tr("tableModel"), ? ?? ?? ?? ?? ?? ?? ?? ?? ???tr("數據庫錯誤: %1") ? ?? ?? ?? ?? ?? ?? ?? ?? ???.arg(model->lastError().text())); ? ??} } 這里用到了事務操作,真正起提交操作的是model->submitAll()一句,它提交所有更改。 2.進入“撤銷修改”按鈕的單擊信號槽,更改如下: void?MainWindow::on_pushButton_4_clicked() { ? ??model->revertAll(); } 3.在mainwindow.cpp文件中包含頭文件: #include?<QMessageBox> #include?<QSqlError> 4.現在運行程序,我們將“陳剛”改為“李強”,如果我們點擊“撤銷修改”,那么它就會重新改為“陳剛”,而當我們點擊“提交修改”后它就會保存到數據庫,此時再點擊“撤銷修改”就修改不回來了。 可以看到,這個模型可以將所有修改先保存到model中,只有當我們執行提交修改后,才會真正寫入數據庫。當然這也是因為我們在最開始設置了它的保存策略: model->setEditStrategy(QSqlTableModel::OnManualSubmit); 這里的OnManualSubmit表明我們要提交修改才能使其生效。 三、查詢操作 1.進入“查詢”按鈕的單擊信號槽,更改如下: void?MainWindow::on_pushButton_clicked() { ? ??QString?name?=?ui->lineEdit->text(); ? ??//根據姓名進行篩選 ? ??model->setFilter(QString("name = '%1'").arg(name)); ? ??//顯示結果 ? ??model->select(); } 使用setFilter()函數進行關鍵字篩選,這個函數是對整個結果集進行查詢。 2.進入“顯示全表”按鈕的單擊信號槽,更改如下: void?MainWindow::on_pushButton_2_clicked() { ? ??model->setTable("student");? ?//重新關聯表 ? ??model->select();? ?//這樣才能再次顯示整個表的內容 } 為了再次顯示整個表的內容,我們需要再次關聯這個表。 3.下面運行程序,輸入一個姓名,點擊“查詢”按鈕后,就可以顯示該記錄了。再點擊“顯示全表”按鈕則返回。如下圖所示。 四、排序操作 分別進入“按id升序排序”和“按id降序排序”按鈕的單擊信號槽,更改如下: //?升序 void?MainWindow::on_pushButton_7_clicked() { ? ??model->setSort(0,?Qt::AscendingOrder);?//id屬性即第0列,升序排列 ? ??model->select(); } //?降序 void?MainWindow::on_pushButton_8_clicked() { ? ??model->setSort(0,?Qt::DescendingOrder); ? ??model->select();?? } 這里使用了setSort()函數進行排序,它有兩個參數,第一個參數表示按第幾個屬性排序,表頭從左向右,最左邊是第0個屬性,這里就是id屬性。第二個參數是排序方法,有升序和降序兩種。運行程序,效果如下圖所示。 五、刪除操作 我們進入“刪除選中行”按鈕的單擊信號槽,更改如下: void?MainWindow::on_pushButton_6_clicked() { ? ??//獲取選中的行 ? ??int?curRow?=?ui->tableView->currentIndex().row(); ? ? ? ??//刪除該行 ? ??model->removeRow(curRow); ? ? ? ??int?ok?=?QMessageBox::warning(this,tr("刪除當前行!"),tr("你確定" ? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??"刪除當前行嗎?"), ? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??QMessageBox::Yes,QMessageBox::No); ? ??if(ok?==?QMessageBox::No) ? ??{ ? ?? ??model->revertAll();?//如果不刪除,則撤銷 ? ??} ? ??else?model->submitAll();?//否則提交,在數據庫中刪除該行?? } 刪除行的操作會先保存在model中,當我們執行了submitAll()函數后才會真正的在數據庫中刪除該行。這里我們使用了一個警告框來讓用戶選擇是否真得要刪除該行。運行程序,效果如下圖所示。 我們點擊第二行,然后單擊“刪除選中行”按鈕,出現了警告框。這時你會發現,表中的第二行前面出現了一個小感嘆號,表明該行已經被修改了,但是還沒有真正的在數據庫中修改,這時的數據有個學名叫臟數據(Dirty Data)。當我們按鈕“Yes”按鈕后數據庫中的數據就會被刪除,如果按下“No”,那么更改就會取消。 六、插入操作 我們進入“添加記錄”按鈕的單擊信號槽,更改如下: void?MainWindow::on_pushButton_5_clicked() { ? ??int?rowNum?=?model->rowCount();?//獲得表的行數 ? ??int?id?=?10; ? ??model->insertRow(rowNum);?//添加一行 ? ??model->setData(model->index(rowNum,0),id); ? ??//model->submitAll(); //可以直接提交 } 在表的最后添加一行,因為在student表中我們設置了id號是主鍵,所以這里必須使用setData()函數給新加的行添加id屬性的值,不然添加行就不會成功。這里可以直接調用submitAll()函數進行提交,也可以利用“提交修改”按鈕進行提交。運行程序,效果如下圖所示。 按下“添加記錄”按鈕后,就添加了一行,不過在該行的前面有個星號,如果我們按下“提交修改”按鈕,這個星號就會消失。當然,如果我們將上面代碼里的提交函數的注釋去掉,也就不會有這個星號了。 結語 可以看到這個模型很強大,而且完全脫離了SQL語句,就算你不怎么懂數據庫知識,也可以利用它進行大部分常用的操作。我們也看到了,這個模型提供了緩沖區,可以先將修改保存起來,當我們執行提交函數時,再去真正地修改數據庫。當然,這個模型比前面的模型更高級,前面講的所有操作,在這里都能執行。 涉及到的源碼:??tableModel.zip?? |
總結
以上是生活随笔為你收集整理的[Qt教程] 第25篇 数据库(五)SQL表格模型QSqlTableModel的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [Qt教程] 第28篇 XML(二)使用
- 下一篇: [Qt教程] 第24篇 数据库(四)SQ