【Qt】数据库实战之QSqlQueryModel
00. 目錄
文章目錄
- 00. 目錄
- 01. 概述
- 02. 開發環境
- 03. QSqlQueryModel查詢模型
- 04. QSqlQueryModel常用操作
- 05. QSqlQueryModel自定義模型
- 06. 附錄
01. 概述
Qt中使用了自己的機制來避免使用SQL語句,為開發者提供了更簡單的數據庫操作及數據顯示模型,分別是只讀的QSqlQueryModel,操作單表的QSqlTableModel以及可以支持外鍵的QSqlRelationalTableModel。
02. 開發環境
Windows系統:Windows10
Qt版本:Qt5.15或者Qt6
03. QSqlQueryModel查詢模型
3.1 新建Qt Widgets應用,項目名稱為15SQL,基類為QMainWindow類名為MainWindow保持默認即可。
3.2 完成后打開15SQL.pro,添加SQL模塊
QT += core gui sql3.3 項目中添加新的C++頭文件,名稱為connection.h,完成后將其內容更改如下:
#ifndef CONNECTION_H #define CONNECTION_H#include <QMessageBox> #include <QSqlDatabase> #include <QSqlQuery> #include <QSqlError> #include <QDebug>static bool createConnection() {QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");db.setDatabaseName("test.db");if (!db.open()){return false;}QSqlQuery query;query.exec("create table student(id int primary key, name varchar(20))");query.exec("insert into student values(1, 'first')");query.exec("insert into student values(2, 'second')");query.exec("insert into student values(3, 'third')");query.exec("insert into student values(4, 'fourth')");query.exec("insert into student values(5, 'fifth')");return true; }#endif // CONNECTION_H這里使用了db.setDatabaseName(“test.db”),沒有再使用以前的內存數據庫,而是使用了真實的文件,這樣后面對數據庫進行的操作就能保存下來了。
3.4 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(); }3.5 進入設計模式,向界面上拖入一個Push Button按鈕,更改顯示文本為“查詢”,然后進入其單擊信號槽,更改如下:
void MainWindow::on_pushButton_clicked() {QSqlQueryModel *model = new QSqlQueryModel(this);model->setQuery("select * from student");model->setHeaderData(0, Qt::Horizontal, tr("ID"));model->setHeaderData(1, Qt::Horizontal, tr("Name"));QTableView *view = new QTableView;view->setModel(model);view->show();}這里新建了QSqlQueryModel類對象model,并用setQuery()函數執行了SQL語句“(“select * fromstudent”);”用來查詢整個student表的內容,可以看到,該類并沒有完全避免SQL語句。然后我們設置了表中字段顯示時的名字。最后我們建立了一個視圖view,并將這個model模型關聯到視圖中,這樣數據庫中的數據就能在窗口上的表中顯示出來了。
執行結果如下:
04. QSqlQueryModel常用操作
4.1 在查詢按鈕槽函數中繼續添加如下代碼:
void MainWindow::on_pushButton_clicked() {QSqlQueryModel *model = new QSqlQueryModel(this);model->setQuery("select * from student");model->setHeaderData(0, Qt::Horizontal, tr("ID"));model->setHeaderData(1, Qt::Horizontal, tr("Name"));QTableView *view = new QTableView;view->setModel(model);view->show();//列數int column = model->columnCount();//行數int row = model->rowCount();//獲取記錄QSqlRecord record = model->record(1);QModelIndex index = model->index(1, 1);qDebug() << "column num: " << column << Qt::endl<< "row num: " << row << Qt::endl<< "record: " << record << Qt::endl<< "index(1, 1): " << index.data();}執行結果
column num: 2 row num: 5 record: QSqlRecord(2)0: QSqlField("id", int, tableName: "student", generated: yes, typeID: 1, autoValue: false, readOnly: false) "2" 1: QSqlField("name", QString, tableName: "student", generated: yes, typeID: 3, autoValue: false, readOnly: false) "second" index(1, 1): QVariant(QString, "second")4.2 直接使用QSqlQuery來執行SQL語句
void MainWindow::on_pushButton_clicked() {QSqlQueryModel *model = new QSqlQueryModel(this);model->setQuery("select * from student");model->setHeaderData(0, Qt::Horizontal, tr("ID"));model->setHeaderData(1, Qt::Horizontal, tr("Name"));QTableView *view = new QTableView;view->setModel(model);view->show();QSqlQuery query = model->query();query.exec("select * from student where id = 2");query.next();qDebug() << query.value(0).toInt() << " " << query.value(1).toString() << Qt::endl;}執行結果
2 "second"4.3 使用QSqlQuery添加數據
void MainWindow::on_pushButton_clicked() {QSqlQueryModel *model = new QSqlQueryModel(this);model->setQuery("select * from student");model->setHeaderData(0, Qt::Horizontal, tr("ID"));model->setHeaderData(1, Qt::Horizontal, tr("Name"));QTableView *view = new QTableView;view->setModel(model);view->show();QSqlQuery query = model->query();query.exec("insert into student values(10, 'deng10')");}然后運行程序,發現最后添加的記錄并沒有顯示出來,當關閉表格窗口,再次單擊查詢按鈕的時候才顯示出來。
我們執行了添加記錄的SQL語句,但是在添加記錄之前,查詢結果就已經顯示了,所以我們的更新沒能動態的顯示出來。為了能讓其動態地顯示我們的更新,可以將槽最后添加的代碼更改如下:
void MainWindow::on_pushButton_clicked() {QSqlQueryModel *model = new QSqlQueryModel(this);model->setQuery("select * from student");model->setHeaderData(0, Qt::Horizontal, tr("ID"));model->setHeaderData(1, Qt::Horizontal, tr("Name"));QTableView *view = new QTableView;view->setModel(model);view->show();QSqlQuery query = model->query();query.exec("insert into student values(10, 'deng10')");//再次執行查詢model->setQuery("select * from student");view->show();}05. QSqlQueryModel自定義模型
QSqlQueryModel模型默認是只讀的,所以在窗口上并不能對表格中的內容進行修改。但是我們可以創建自己的模型,然后按照自己的意愿來顯示數據和修改數據。要想使其可讀寫,需要自己的類繼承自QSqlQueryModel,并且重寫setData() 和 flags() 兩個函數。如果我們要改變數據的顯示,就要重寫data() 函數。
我們將要實現student表查詢結果的id字段顯示紅色,name字段可編輯。
5.1 向項目中添加新的C++類,類名為MySqlQueryModel,基類Base class保持Custom,然后在下面手動填寫QSqlQueryModel。
5.2 mysqlquerymodel.h內容如下:
#ifndef MYSQLQUERYMODEL_H #define MYSQLQUERYMODEL_H#include <QSqlQueryModel>class MySqlQueryModel : public QSqlQueryModel { public:explicit MySqlQueryModel(QObject *parent = 0);// QAbstractItemModel interface public:QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;bool setData(const QModelIndex &index, const QVariant &value, int role);Qt::ItemFlags flags(const QModelIndex &index) const;private:bool setName(int id, const QString &name);void refresh(); };#endif // MYSQLQUERYMODEL_H5.3 mysqlquerymodel.cpp文件內容如下
#include "mysqlquerymodel.h" #include <QSqlQuery> #include <QColor> #include <QModelIndex>MySqlQueryModel::MySqlQueryModel(QObject *parent):QSqlQueryModel(parent) {}//添加數據 bool MySqlQueryModel::setData(const QModelIndex &index, const QVariant &value, int role) {Q_UNUSED(role)if (index.column() < 1 || index.column() > 2){return false;}QModelIndex primaryKeyIndex = QSqlQueryModel::index(index.row(), 0);//獲取ID號int id = data(primaryKeyIndex).toInt();clear();bool ret = false;//設置第二個字段可以更改if (index.column() == 1){ret = setName(id, value.toString());}refresh();return ret; }//返回表格是否可以被更改的標志 Qt::ItemFlags MySqlQueryModel::flags(const QModelIndex &index) const {Qt::ItemFlags flags = QSqlQueryModel::flags(index);//第二個字段可以更改if (index.column() == 1){flags |= Qt::ItemIsEditable;}return flags; }//更改數據顯示樣式 QVariant MySqlQueryModel::data(const QModelIndex &index, int role) const {QVariant value = QSqlQueryModel::data(index, role);//第一個字段的字體顏色為紅色if (role == Qt::TextColorRole && index.column() == 0){return QVariant::fromValue(QColor(Qt::red));}return value; }//添加name字段的值 bool MySqlQueryModel::setName(int id, const QString &name) {QSqlQuery query;query.prepare("update student set name = ? where id = ?");query.addBindValue(name);query.addBindValue(id);return query.exec(); }//更新顯示 void MySqlQueryModel::refresh() {setQuery("select * from student");setHeaderData(0, Qt::Horizontal, QObject::tr("id"));setHeaderData(1, Qt::Horizontal, QObject::tr("name")); }5.4 查詢按鈕槽函數更改如下:
void MainWindow::on_pushButton_clicked() {QSqlQueryModel *model = new QSqlQueryModel(this);model->setQuery("select * from student");model->setHeaderData(0, Qt::Horizontal, tr("ID"));model->setHeaderData(1, Qt::Horizontal, tr("Name"));QTableView *view = new QTableView;view->setModel(model);view->show();//創建自己的模型MySqlQueryModel *model1 = new MySqlQueryModel(this);model1->setQuery("select * from student");model1->setHeaderData(0, Qt::Horizontal, tr("ID"));model1->setHeaderData(1, Qt::Horizontal, tr("Name"));QTableView *view1 = new QTableView;view1->setModel(model1);view1->show();}執行結果如下:
06. 附錄
6.1 Qt教程匯總
網址:https://dengjin.blog.csdn.net/article/details/115174639
6.2 源碼下載
網址:【Qt】數據庫實戰之QSqlQueryModel.rar
總結
以上是生活随笔為你收集整理的【Qt】数据库实战之QSqlQueryModel的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Qt】数据库实战(三)
- 下一篇: 【Qt】数据库实战之QSqlTableM