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