欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Qt實(shí)現(xiàn)SqlTableModel映射組件應(yīng)用小結(jié)

 更新時(shí)間:2023年12月29日 16:29:40   作者:微軟技術(shù)分享  
在Qt中提供了QSqlTableModel模型類,它為開(kāi)發(fā)者提供了一種直觀的方式來(lái)與數(shù)據(jù)庫(kù)表格進(jìn)行交互,本文就來(lái)介紹一下Qt實(shí)現(xiàn)SqlTableModel映射組件應(yīng)用小結(jié),感興趣的可以了解一下

Qt 是一個(gè)跨平臺(tái)C++圖形界面開(kāi)發(fā)庫(kù),利用Qt可以快速開(kāi)發(fā)跨平臺(tái)窗體應(yīng)用程序,在Qt中我們可以通過(guò)拖拽的方式將不同組件放到指定的位置,實(shí)現(xiàn)圖形化開(kāi)發(fā)極大的方便了開(kāi)發(fā)效率,本章將重點(diǎn)介紹SqlTableModule組件的常用方法及靈活運(yùn)用。

在多數(shù)情況下我們需要使用SQL的方法來(lái)維護(hù)數(shù)據(jù)庫(kù),但此方式相對(duì)較為繁瑣對(duì)于表格等數(shù)據(jù)的編輯非常不友好,在Qt中提供了QSqlTableModel模型類,它為開(kāi)發(fā)者提供了一種直觀的方式來(lái)與數(shù)據(jù)庫(kù)表格進(jìn)行交互。通過(guò)使用該組件可以將數(shù)據(jù)庫(kù)與特定的組件進(jìn)行關(guān)聯(lián),一旦關(guān)聯(lián)被建立那么用戶的所有操作均可以使用函數(shù)的方式而無(wú)需使用SQL語(yǔ)句,該特性有點(diǎn)類似于ORM對(duì)象關(guān)系映射機(jī)制。

在接下來(lái)的章節(jié)中,我們將學(xué)習(xí)如何配置 QSqlTableModel、與數(shù)據(jù)庫(kù)進(jìn)行交互、實(shí)現(xiàn)數(shù)據(jù)的動(dòng)態(tài)顯示和編輯,首先讀者應(yīng)繪制好UI界面,本次案例界面稍顯復(fù)雜,讀者可自行完成如下案例的繪制;

以下是 QSqlTableModel 類的一些常用方法,包括方法名、參數(shù)以及簡(jiǎn)要說(shuō)明。這里列舉的方法并非全部,而是一些常見(jiàn)的方法,更詳細(xì)的信息可以參考官方文檔。

方法描述
QSqlTableModel(QObject *parent = nullptr, QSqlDatabase db = QSqlDatabase())構(gòu)造函數(shù),創(chuàng)建 QSqlTableModel 對(duì)象。
setTable(const QString &tableName)設(shè)置要操作的數(shù)據(jù)庫(kù)表名。
select()執(zhí)行查詢操作,從數(shù)據(jù)庫(kù)中獲取數(shù)據(jù)。
rowCount(const QModelIndex &parent = QModelIndex()) const返回模型中的行數(shù)。
columnCount(const QModelIndex &parent = QModelIndex()) const返回模型中的列數(shù)。
record(int row)返回指定行的記錄。
setFilter(const QString &filter)設(shè)置用于過(guò)濾數(shù)據(jù)的條件。
setSort(int column, Qt::SortOrder order)設(shè)置排序的列和排序規(guī)則。
setEditStrategy(QSqlTableModel::EditStrategy strategy)設(shè)置編輯策略,決定何時(shí)將修改提交到數(shù)據(jù)庫(kù)。
setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole)設(shè)置模型中指定索引的數(shù)據(jù)。
data(const QModelIndex &index, int role = Qt::DisplayRole) const返回模型中指定索引的數(shù)據(jù)。
addRecord(const QSqlRecord &values)添加一條記錄到模型中。
removeRow(int row)從模型中刪除指定行。
insertRecord(int row, const QSqlRecord &record)在指定位置插入一條記錄。
submitAll()提交所有對(duì)模型的修改到數(shù)據(jù)庫(kù)。
revertAll()撤銷(xiāo)對(duì)模型的所有修改。
setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole)設(shè)置表頭數(shù)據(jù)。
indexInQuery(const QSqlQuery &query) const返回查詢中模型的索引。

這些方法提供了對(duì) QSqlTableModel 進(jìn)行數(shù)據(jù)操作、過(guò)濾、排序以及提交修改的基本手段。通過(guò)這些方法,可以在應(yīng)用程序中方便地操作數(shù)據(jù)庫(kù)表格的數(shù)據(jù)。

1.1 初始化組件

首先我們來(lái)看一下MainWindow初始化部分是如何工作的,主要實(shí)現(xiàn)了以下功能:

打開(kāi)數(shù)據(jù)庫(kù)

首先使用SQLite數(shù)據(jù)庫(kù)驅(qū)動(dòng)連接名為"database.db"的數(shù)據(jù)庫(kù)文件。如果數(shù)據(jù)庫(kù)連接失敗,函數(shù)直接返回。接著通過(guò)新建一個(gè)QSqlTableModel類,并調(diào)用setTable來(lái)打開(kāi)一個(gè)數(shù)據(jù)表,設(shè)置編輯策略為 OnManualSubmit,即手動(dòng)提交修改。并通過(guò)setSort函數(shù)來(lái)設(shè)置排序方式為根據(jù)ID字段升序Qt::AscendingOrder排列。

DB = QSqlDatabase::addDatabase("QSQLITE");
DB.setDatabaseName("./database.db");
if (!DB.open())
{
    return;
}

tabModel = new QSqlTableModel(this, DB);
tabModel->setTable("Student");
tabModel->setEditStrategy(QSqlTableModel::OnManualSubmit);
tabModel->setSort(tabModel->fieldIndex("id"), Qt::AscendingOrder);
if (!(tabModel->select()))
{
    return;
}

設(shè)置字段名稱

此處我們數(shù)據(jù)庫(kù)中有6個(gè)字段,也就需要設(shè)置數(shù)據(jù)庫(kù)字段與表格關(guān)聯(lián),如下則是對(duì)字段的動(dòng)態(tài)關(guān)聯(lián)。

tabModel->setHeaderData(tabModel->fieldIndex("id"),Qt::Horizontal,"Uid");
tabModel->setHeaderData(tabModel->fieldIndex("name"),Qt::Horizontal,"Uname");
tabModel->setHeaderData(tabModel->fieldIndex("sex"),Qt::Horizontal,"Usex");
tabModel->setHeaderData(tabModel->fieldIndex("age"),Qt::Horizontal,"Uage");
tabModel->setHeaderData(tabModel->fieldIndex("mobile"),Qt::Horizontal,"Umobile");
tabModel->setHeaderData(tabModel->fieldIndex("city"),Qt::Horizontal,"Ucity");

關(guān)聯(lián)選擇模型和數(shù)據(jù)模型

通過(guò)創(chuàng)建 QItemSelectionModel 對(duì)象 theSelection 并關(guān)聯(lián)到 tabModel模型,將數(shù)據(jù)模型和選擇模型關(guān)聯(lián)到 ui->tableView,并設(shè)置選擇模式為行選擇模式。

theSelection = new QItemSelectionModel(tabModel);
ui->tableView->setModel(tabModel);
ui->tableView->setSelectionModel(theSelection);
ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);

創(chuàng)建數(shù)據(jù)映射

創(chuàng)建 QDataWidgetMapper 對(duì)象 dataMapper,將數(shù)據(jù)模型設(shè)置為 tabModel,設(shè)置提交策略為 AutoSubmit,即自動(dòng)提交修改。并將 “name” 字段映射到 ui->lineEdit_name,默認(rèn)選中第一條映射記錄。

dataMapper = new QDataWidgetMapper();
dataMapper->setModel(tabModel);
dataMapper->setSubmitPolicy(QDataWidgetMapper::AutoSubmit);
dataMapper->addMapping(ui->lineEdit_name, tabModel->fieldIndex("name"));
dataMapper->toFirst();

信號(hào)和槽連接

當(dāng)選擇模型中的當(dāng)前行改變時(shí),連接到槽函數(shù) on_currentRowChanged,用于在右側(cè)編輯框中輸出當(dāng)前選擇的記錄。

connect(theSelection, SIGNAL(currentRowChanged(QModelIndex, QModelIndex)), this, SLOT(on_currentRowChanged(QModelIndex, QModelIndex)));

這個(gè)槽函數(shù)的實(shí)現(xiàn)如下所示,當(dāng)行被點(diǎn)擊后執(zhí)行獲取name/mobile字段,并放入映射數(shù)據(jù)集中的lineEdit編輯框中,使其能夠動(dòng)態(tài)的顯示數(shù)據(jù)列表。

void MainWindow::on_currentRowChanged(const QModelIndex &current, const QModelIndex &previous)
{
    Q_UNUSED(previous);

    dataMapper->setCurrentIndex(current.row());      // 更細(xì)數(shù)據(jù)映射的行號(hào)
    int curRecNo=current.row();                      // 獲取行號(hào)
    QSqlRecord  curRec=tabModel->record(curRecNo);   // 獲取當(dāng)前記錄

    QString uname = curRec.value("name").toString();     // 取出數(shù)據(jù)
    QString mobile = curRec.value("mobile").toString();

    ui->lineEdit_name->setText(uname);                   // 設(shè)置到編輯框
    ui->lineEdit_mobile->setText(mobile);
}

最后在UI文件的底部有一個(gè)comboBox組件,我們通過(guò)動(dòng)態(tài)的查詢記錄,并將其賦值為第一個(gè)字段元素,其代碼如下所示;

QSqlRecord emptyRec=tabModel->record();           //獲取空記錄,只有字段名
for (int i=0;i<emptyRec.count();i++)
{
    ui->comboBox->addItem(emptyRec.fieldName(i));
}

這段代碼實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的數(shù)據(jù)庫(kù)瀏覽和編輯界面,用戶可以通過(guò)表格展示的方式查看和編輯 “Student” 表格中的數(shù)據(jù)。當(dāng)程序運(yùn)行后則可以看到如下圖所示的初始化部分;

1.2 數(shù)據(jù)處理

1.2.1 新增一條記錄

當(dāng)用戶按下on_pushButton_add_clicked按鈕時(shí),則會(huì)在表格中新增一條記錄,并設(shè)置默認(rèn)值的功能。下面是代碼的詳細(xì)解釋:

插入新行

在表格模型 tabModel 的末尾插入一行新記錄。QModelIndex() 是一個(gè)空的索引,表示插入到末尾。

tabModel->insertRow(tabModel->rowCount(), QModelIndex());

獲取最后一行的索引

獲取剛剛插入的行的索引,這里假設(shè) “name” 字段對(duì)應(yīng)的列索引是 1。

QModelIndex curIndex = tabModel->index(tabModel->rowCount() - 1, 1);

清空選擇項(xiàng)并設(shè)置新行為當(dāng)前選擇行

清空當(dāng)前選擇項(xiàng),然后將剛剛插入的行設(shè)為當(dāng)前選擇行,并選擇該行。

theSelection->clearSelection();
theSelection->setCurrentIndex(curIndex, QItemSelectionModel::Select);

獲取當(dāng)前行號(hào)

獲取當(dāng)前行的行號(hào)。

int currow = curIndex.row();

設(shè)置自動(dòng)生成的編號(hào)和默認(rèn)值

這段代碼的作用是在表格模型中插入一行新記錄,然后設(shè)置該行的默認(rèn)值,其中 “Uid” 字段會(huì)自動(dòng)生成一個(gè)編號(hào),“Usex” 字段默認(rèn)為 “M”,“Uage” 字段默認(rèn)為 “0”。

  • 自動(dòng)生成編號(hào),假設(shè) “Uid” 字段對(duì)應(yīng)的列索引是 0。
  • 將 “Usex” 字段設(shè)置為 “M”。
  • 將 “Uage” 字段設(shè)置為 “0”。
tabModel->setData(tabModel->index(currow, 0), 1000 + tabModel->rowCount());
tabModel->setData(tabModel->index(currow, 2), "M");
tabModel->setData(tabModel->index(currow, 3), "0");

運(yùn)行代碼,讀者可自行點(diǎn)擊增加記錄按鈕,每次點(diǎn)擊均會(huì)在表格中提供新行,當(dāng)讀者點(diǎn)擊on_pushButton_save_clicked保存按鈕是則會(huì)調(diào)用submitAll()該函數(shù)用于將數(shù)據(jù)提交到數(shù)據(jù)庫(kù)中存儲(chǔ),如下圖所示;

1.2.2 插入一條記錄

在 TableView 中當(dāng)前選擇行的上方插入一行新記錄,并自動(dòng)生成編號(hào)。下面是代碼的詳細(xì)解釋:

獲取當(dāng)前選擇行的索引和行號(hào)

獲取當(dāng)前選擇的單元格的索引和行號(hào)。

QModelIndex curIndex = ui->tableView->currentIndex();
int currow = curIndex.row();

在當(dāng)前行上方插入一行新記錄

在表格模型 tabModel 的當(dāng)前選擇行(curIndex.row())的上方插入一行新記錄。QModelIndex() 是一個(gè)空的索引,表示插入到指定行的上方。

tabModel->insertRow(curIndex.row(), QModelIndex());

設(shè)置自動(dòng)生成的編號(hào)

自動(dòng)生成編號(hào),假設(shè) “Uid” 字段對(duì)應(yīng)的列索引是 0。

tabModel->setData(tabModel->index(currow, 0), 1000 + tabModel->rowCount());

清除已有選擇并將當(dāng)前選擇行設(shè)為新插入的行

清空已有選擇項(xiàng),然后將當(dāng)前選擇行設(shè)為新插入的行,并選擇該行。

theSelection->clearSelection();
theSelection->setCurrentIndex(curIndex, QItemSelectionModel::Select);

當(dāng)上述代碼運(yùn)行后則可以實(shí)現(xiàn)在指定行的上方插入一行新紀(jì)錄,并為新插入的行生成一個(gè)自增的編號(hào),其效果如下圖所示;

對(duì)于刪除一條記錄來(lái)說(shuō)則可以通過(guò)調(diào)用tabModel->removeRow(curIndex.row())來(lái)實(shí)現(xiàn)刪除所選行,因?yàn)槠鋵?shí)現(xiàn)起來(lái)很簡(jiǎn)單此處就不再演示,具體實(shí)現(xiàn)細(xì)節(jié)可以參考附件。

1.2.3 修改表中記錄

如下所示代碼,用于批量修改表格中所有記錄的 “Uage” 字段值為某個(gè)固定的年齡。下面是代碼的詳細(xì)解釋:

檢查是否有記錄

如果表格中沒(méi)有記錄,則直接返回,不執(zhí)行后續(xù)的批量修改操作。

if (tabModel->rowCount() == 0)
    return;

循環(huán)遍歷每一行記錄并修改年齡

首先使用 tabModel->record(i) 獲取表格模型中的第 i 行記錄,接著使用 ui->lineEdit->text() 獲取用戶在 QLineEdit 中輸入的文本,作為新的年齡值,并通過(guò) aRec.setValue("age", ...) 設(shè)置 “age” 字段的新值,最后使用 tabModel->setRecord(i, aRec) 將修改后的記錄設(shè)置回表格模型中的相應(yīng)行。

for (int i = 0; i < tabModel->rowCount(); i++)
{
    QSqlRecord aRec = tabModel->record(i);                // 獲取當(dāng)前記錄
    aRec.setValue("age", ui->lineEdit->text());           // 設(shè)置數(shù)據(jù),使用 QLineEdit 中的文本作為新的年齡值
    tabModel->setRecord(i, aRec);                         // 將修改后的記錄設(shè)置回表格模型中的相應(yīng)行
}

提交修改

使用 tabModel->submitAll() 提交對(duì)表格模型的所有修改,將修改保存到數(shù)據(jù)庫(kù)中。

tabModel->submitAll();

上述代碼實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的批量修改操作,將表格中所有記錄的 “Uage” 字段值設(shè)置為用戶在 QLineEdit 中輸入的年齡值。請(qǐng)注意,這里沒(méi)有對(duì)輸入的年齡值進(jìn)行驗(yàn)證,確保輸入的是合法的數(shù)字。在實(shí)際應(yīng)用中,可能需要添加一些輸入驗(yàn)證和錯(cuò)誤處理的邏輯。

1.2.4 表記錄的排序

升序與降序排列

對(duì)表中記錄的排序可以使用模型提供的setSort函數(shù)來(lái)實(shí)現(xiàn),通過(guò)對(duì)該字段第二個(gè)參數(shù)設(shè)置為Qt::AscendingOrder則是升序排序,反之如果設(shè)置為Qt::DescendingOrder則為降序排序。

如下所示代碼用于根據(jù)用戶選擇的字段對(duì)表格進(jìn)行排序,并重新執(zhí)行查詢以更新表格數(shù)據(jù)。下面是代碼的詳細(xì)解釋:

  • ui->comboBox->currentIndex() 獲取用戶在 QComboBox 中選擇的字段的索引。
  • Qt::AscendingOrder 表示升序排序。
  • tabModel->select()執(zhí)行對(duì)數(shù)據(jù)庫(kù)的查詢操作,重新獲取數(shù)據(jù)并應(yīng)用排序。
// 升序排序
tabModel->setSort(ui->comboBox->currentIndex(), Qt::AscendingOrder);
// 降序排序
tabModel->setSort(ui->comboBox->currentIndex(),Qt::DescendingOrder);
// 刷新查詢
tabModel->select();

上述代碼的作用是根據(jù)用戶在下拉框中選擇的字段進(jìn)行升序或降序排序,并將排序后的結(jié)果重新加載到表格中。在使用這段代碼之前,用戶需要在 QComboBox 中選擇一個(gè)字段,作為排序的依據(jù)。以升序排序?yàn)槔?,輸出效果如下圖所示;

到此這篇關(guān)于Qt實(shí)現(xiàn)SqlTableModel映射組件應(yīng)用小結(jié)的文章就介紹到這了,更多相關(guān)Qt SqlTableModel映射內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言打印輸出楊輝三角

    C語(yǔ)言打印輸出楊輝三角

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言打印輸出楊輝三角,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • C++ 虛函數(shù)與純虛函數(shù)的使用與區(qū)別

    C++ 虛函數(shù)與純虛函數(shù)的使用與區(qū)別

    本文主要介紹了C++ 虛函數(shù)與純虛函數(shù)的使用與區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • C++中類模板的應(yīng)用你了解多少

    C++中類模板的應(yīng)用你了解多少

    這篇文章主要為大家詳細(xì)介紹了C++中類模板的應(yīng)用,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-02-02
  • 詳解C語(yǔ)言的exp()函數(shù)和ldexp()函數(shù)以及frexp()函數(shù)

    詳解C語(yǔ)言的exp()函數(shù)和ldexp()函數(shù)以及frexp()函數(shù)

    這篇文章主要介紹了詳解C語(yǔ)言的exp()函數(shù)和ldexp()函數(shù)以及frexp()函數(shù),注意這三個(gè)函數(shù)雖然看起來(lái)相似但實(shí)際功能卻大相徑庭!需要的朋友可以參考下
    2015-08-08
  • 華為面試題答案找出最大長(zhǎng)度子字符串

    華為面試題答案找出最大長(zhǎng)度子字符串

    找出最大長(zhǎng)度子字符串,打印并且返回長(zhǎng)度。 例如 str = "abc123abcd234abcdefgha324adsdawqdasdaseqqwe345abchded",看下面的代碼實(shí)現(xiàn)吧
    2013-12-12
  • C++實(shí)現(xiàn)簡(jiǎn)單迷宮游戲

    C++實(shí)現(xiàn)簡(jiǎn)單迷宮游戲

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡(jiǎn)單迷宮游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-01-01
  • C語(yǔ)言實(shí)現(xiàn)順序表的基本操作指南(注釋很詳細(xì))

    C語(yǔ)言實(shí)現(xiàn)順序表的基本操作指南(注釋很詳細(xì))

    線性表是最簡(jiǎn)單的數(shù)據(jù)結(jié)構(gòu),而順序表又是最簡(jiǎn)單的線性表,其基本思想是用一段地址連續(xù)的儲(chǔ)存單元依次存儲(chǔ)線性表的數(shù)據(jù)元素,下面這篇文章主要給大家介紹了關(guān)于C語(yǔ)言實(shí)現(xiàn)順序表的基本操作,需要的朋友可以參考下
    2021-10-10
  • c++中template對(duì)字符串的處理方法

    c++中template對(duì)字符串的處理方法

    這篇文章主要介紹了c++中template對(duì)字符串的處理方法,需要的朋友可以參考下
    2014-07-07
  • c語(yǔ)言中scanf的基本用法

    c語(yǔ)言中scanf的基本用法

    這篇文章主要給大家介紹了關(guān)于c語(yǔ)言中scanf的基本用法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • C++類中的繼承實(shí)例詳解

    C++類中的繼承實(shí)例詳解

    這篇文章主要介紹了C++類中的繼承實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-07-07

最新評(píng)論