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