QT M/V架構開發實戰:QSqlQueryModel/ QSqlTableModel/ QSqlRelationalTableModel介紹

目錄

    • @[TOC](目錄)
  • 前言
  • 一、初步介紹
  • 二、QSqlQueryModel
      • 1.基礎定位
      • 2.特點
      • 3.核心接口
      • 4.典型用法
      • 5.優缺點
  • 三、QSqlTableModel
      • 1.基礎定位
      • 2.特點
      • 3.核心接口
      • 4.典型用法
      • 5.優缺點
  • 四、QSqlRelationalTableModel
      • 1.基礎定位
      • 2.特點
      • 3.核心接口
      • 4.典型用法 (示例:employees表有 dept_id外鍵,關聯 departments表的 id和 name字段)
      • 5.優缺點
  • 五、重要注意事項

前言


本文主要介紹的是使用代碼生成的情況下對控件的介紹,包括擁有的功能及能修改的樣式,也會說明在qtdesiner拖拽控件生成和使用代碼生成控件的區別(如果有的話,遇到了的會說),此版本不屬于最終版本,以后遇到什么新奇的點會繼續更新!本文基于QT官方的文檔進行的編寫,QT版本為qt 5.14.0,編寫環境為Windows11。不得不說官方文檔真是個好東西,有時候有些不會的上去一看就能有靈感解決了,可惜沒有中文版本的。

一、初步介紹

因為這三個模型類基本都是將SQL數據庫中的數據引入模型的,用到的機會也不是很多,所以就放在一起介紹了。

?核心目標:?? 將數據庫查詢結果或表數據無縫展示在 Qt 的視圖控件(如 QTableView、QListView)中,并支持一定程度的數據操作(編輯、插入、刪除)。

??共同基礎:??
??依賴 Qt SQL 模塊:?? 使用前需包含 ,并在項目文件 (.pro) 中添加 QT += sql。
??需要數據庫連接:?? 使用前必須建立有效的數據庫連接 (QSqlDatabase)。
??視圖綁定:?? 通過 view->setModel(model)將模型綁定到視圖。
??數據角色:?? 通過 data(index, role)獲取數據,支持 Qt::DisplayRole(顯示文本)、Qt::EditRole(編輯值) 等。
??只讀屬性:?? QSqlQueryModel默認是只讀的。QSqlTableModel和 QSqlRelationalTableModel默認是可編輯的(需設置 setEditStrategy)。
??列與字段映射:?? 模型中的列 (column) 對應 SQL 查詢結果或數據庫表中的字段 (field)。

二、QSqlQueryModel

1.基礎定位

?? 用于執行任意 SQL SELECT查詢并將結果集展示在視圖中。??核心是執行查詢并獲取結果。??

2.特點

只讀 (默認):?? 僅用于顯示查詢結果,不支持通過模型直接修改數據、插入或刪除行。

??靈活性高:?? 可以執行任何 SELECT語句,包括多表連接、聚合函數、子查詢等復雜查詢。

??輕量:?? 主要職責是執行查詢和緩存結果。

??手動刷新:?? 調用 setQuery()執行新查詢來刷新數據。不自動監聽數據庫變化。

3.核心接口

// 設置/執行查詢 (刷新模型)
void setQuery(const QSqlQuery &query);
void setQuery(const QString &query, const QSqlDatabase &db = QSqlDatabase());// 獲取底層查詢對象
QSqlQuery query() const;// 獲取記錄 (行) 信息
QSqlRecord record() const; // 返回一個空記錄,包含字段信息
QSqlRecord record(int row) const; // 獲取指定行的記錄 (包含所有字段值)// 獲取字段名 (列名)
QString headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
// 通常需要重寫 headerData() 來設置列標題為字段名

4.典型用法

QSqlQueryModel *model = new QSqlQueryModel;
model->setQuery("SELECT id, name, salary FROM employees WHERE department = 'Sales'", myDatabase);
tableView->setModel(model);
// 重寫 headerData 以顯示字段名

5.優缺點

優點: 靈活,能處理復雜查詢。
缺點: 只讀,需要手動刷新,不直接支持編輯。

三、QSqlTableModel

1.基礎定位

專門用于操作??單個數據庫表??。提供對表中數據的??讀寫??訪問(CRUD:Create, Read, Update, Delete)。

2.特點

可讀寫 (默認):?? 支持通過模型接口 (setData, insertRow, removeRow) 修改數據、插入新行、刪除行。

??基于單表:?? 操作對象是數據庫中的一個表。

??編輯策略 (EditStrategy):?? 控制修改如何提交到數據庫,是核心特性!
QSqlTableModel::OnFieldChange:字段值改變時立即提交。(??不推薦??,效率低且易出錯)。
QSqlTableModel::OnRowChange:當用戶選擇另一行或調用 submit()時提交當前行的所有修改。(常用)。
QSqlTableModel::OnManualSubmit:所有修改都緩存在模型中,直到顯式調用 submitAll()或 revertAll()。(最常用,提供事務控制)。

??過濾與排序:?? 支持通過 setFilter()設置 WHERE 條件,setSort()設置 ORDER BY 條件。調用 select()應用過濾/排序并刷新數據。

??自動生成 SQL:?? 模型內部根據操作自動生成相應的 INSERT, UPDATE, DELETE語句。

3.核心接口

// 設置操作的表和數據庫
void setTable(const QString &tableName);
void setDatabase(const QSqlDatabase &db); // 通常在構造函數設置// 設置編輯策略
void setEditStrategy(QSqlTableModel::EditStrategy strategy);// 執行 SELECT 查詢 (應用過濾/排序,刷新數據)
bool select();// 設置過濾條件 (WHERE 子句,不帶 WHERE 關鍵字)
void setFilter(const QString &filter);
// 設置排序 (ORDER BY 子句,不帶 ORDER BY 關鍵字)
void setSort(int column, Qt::SortOrder order);// 數據操作
bool insertRow(int row, const QModelIndex &parent = QModelIndex()); // 插入空行
bool removeRow(int row, const QModelIndex &parent = QModelIndex()); // 刪除行
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; // 修改單元格// 提交/回滾修改 (根據 EditStrategy)
bool submit(); // 提交當前行修改 (OnRowChange)
bool submitAll(); // 提交所有緩存的修改 (OnManualSubmit)
void revert(); // 回滾當前行修改
void revertAll(); // 回滾所有緩存的修改// 獲取表結構信息
QSqlRecord record() const; // 返回一個空記錄,包含字段信息
QSqlRecord record(int row) const; // 獲取指定行的記錄
QString fieldName(int column) const; // 獲取列名 (字段名)

4.典型用法

QSqlTableModel *model = new QSqlTableModel(parent, myDatabase);
model->setTable("employees");
model->setEditStrategy(QSqlTableModel::OnManualSubmit); // 推薦
model->setFilter("department = 'Sales'"); // 設置過濾
model->setSort(2, Qt::AscendingOrder); // 按第3列(索引2)升序
model->select(); // 執行查詢,加載數據tableView->setModel(model);
tableView->setEditTriggers(QAbstractItemView::DoubleClicked); // 啟用視圖編輯// 點擊保存按鈕時提交所有修改
connect(saveButton, &QPushButton::clicked, model, &QSqlTableModel::submitAll);
// 點擊取消按鈕時回滾所有修改
connect(cancelButton, &QPushButton::clicked, model, &QSqlTableModel::revertAll);

5.優缺點

優點: 支持對單表進行完整的 CRUD 操作,集成度高,使用相對方便。
缺點: 僅限于單表操作。復雜查詢(如多表 JOIN)需要繞行或使用其他模型。OnManualSubmit需要手動管理提交。

四、QSqlRelationalTableModel

1.基礎定位

繼承自 QSqlTableModel。專門用于處理具有??外鍵 (Foreign Key)?? 關系的單表。它允許你在顯示主表記錄時,用另一個關聯表(Lookup Table)中的??友好名稱??代替原始的外鍵 ID 值。

2.特點

繼承 QSqlTableModel:?? 擁有 QSqlTableModel的所有功能(CRUD、過濾、排序、編輯策略)。

??關系映射 (Relation):?? 核心功能! 將主表中的外鍵字段映射到關聯表的某個字段(通常是顯示名稱)。

??下拉框支持:?? 在可編輯的視圖(如 QTableView)中,編輯具有關系的字段時,會自動提供一個下拉框 (QComboBox),列出關聯表中的可選值。

??內部使用 JOIN:?? 為了實現關系顯示,模型內部在執行 SELECT時會使用 LEFT JOIN(或類似)將關聯表連接進來。

3.核心接口

// 設置關系 (核心!)
void setRelation(int column, const QSqlRelation &relation);
// QSqlRelation 構造函數: QSqlRelation(tableName, fieldId, fieldDisplay)
//   tableName: 關聯表名
//   fieldId: 關聯表中與主表外鍵字段匹配的 ID 字段 (通常是主鍵)
//   fieldDisplay: 關聯表中要顯示的友好名稱字段// 獲取關系
QSqlRelation relation(int column) const;// 獲取關聯表的模型 (可用于自定義委托等)
QSqlTableModel *relationModel(int column) const;

4.典型用法 (示例:employees表有 dept_id外鍵,關聯 departments表的 id和 name字段)

QSqlRelationalTableModel *model = new QSqlRelationalTableModel(parent, myDatabase);
model->setTable("employees");
model->setEditStrategy(QSqlTableModel::OnManualSubmit);// 設置關系:將 employees 表的第3列 (假設是 dept_id) 映射到 departments 表的 name 字段
model->setRelation(3, QSqlRelation("departments", "id", "name"));model->select();tableView->setModel(model);// 為了讓關系列顯示友好名稱并使用下拉框,通常需要設置一個特殊的委托
tableView->setItemDelegate(new QSqlRelationalDelegate(tableView));/*
?效果:??
在 tableView中,原本顯示 dept_id(如 1, 2) 的列,現在會顯示對應的部門名稱 (如 "Sales", "Engineering")。
當用戶雙擊該列進行編輯時,會出現一個下拉框 (QComboBox),列出 departments表中所有的 name值供用戶選擇。用戶選擇后,模型內部實際存儲和操作的仍然是 dept_id。
*/

5.優缺點

優點: 極大地提升了用戶界面友好度,尤其是在處理外鍵關系時。簡化了基于外鍵的選擇操作。
缺點: 仍然基于單表(主表),復雜關系或多表 JOIN 顯示非友好名稱字段可能力不從心。性能可能略低于 QSqlTableModel(因為 JOIN 操作)。

五、重要注意事項

1、事務管理:?? QSqlTableModel和 QSqlRelationalTableModel的 submitAll()操作通常發生在數據庫事務之外。如果需要嚴格的原子性操作,應在調用 submitAll()前后手動管理 QSqlDatabase的事務 (transaction(), commit(), rollback())。

??2、性能:?? 對于大型數據集,QSqlTableModel和 QSqlRelationalTableModel默認會一次性加載所有數據到內存。考慮使用 setQuery分頁 (對 QSqlQueryModel) 或限制過濾條件來優化。

3、??復雜場景:?? 對于非常復雜的數據庫交互(如涉及多個表深度修改、存儲過程調用、特定數據庫特性),直接使用 QSqlQuery結合自定義模型 (QAbstractItemModel) 可能是更靈活的選擇。

??4、委托:?? QSqlRelationalDelegate對于關系列的編輯體驗至關重要。你也可以創建自定義委托來實現更復雜的關系編輯邏輯。

本次分享就到這里了,如果有什么錯誤的話請指正,或者有什么疑問的,也可以在評論區一起探討!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/96678.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/96678.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/96678.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Terraform 從入門到實戰:歷史、原理、功能與阿里云/Azure 上手指南

前言:在云時代,企業的IT基礎設施早已從“幾臺服務器”演變為“橫跨多云的復雜網絡、計算、存儲集群”。但隨之而來的,是管理復雜度的爆炸式增長:開發環境和生產環境不一致、手動配置容易出錯、多云平臺操作方式各異、資源變更難以…

【計算機網絡 | 第10篇】信道復用技術

文章目錄信道復用技術:高效利用通信資源的智慧方案一、頻分復用(FDM):按頻率劃分的并行通道二、時分復用(TDM):按時間分割的輪流占用三、統計時分復用(STDM):…

安卓13_ROM修改定制化-----禁用 Android 導航按鍵的幾種操作

Android 設備的導航按鍵通常包括后退鍵(Back)、主頁鍵(Home)和最近鍵(Recents),這些按鍵位于屏幕底部或設備實體區域。禁用導航按鍵可以幫助在特定應用場景(如信息亭模式或兒童鎖模式)中限制用戶操作。安卓設備上禁用底部虛擬導航鍵(返回、主頁、多任務鍵)有多種方法…

通過S參數測量評估電感阻抗:第2部分

S21雙端口分流和雙端口串聯方法 T這是兩篇文章中的第二篇,專門討論使用網絡分析儀測量 S 參數進行電感阻抗評估主題。上一篇文章 [1] 描述了阻抗測量和計算S11使用單端口分流器、雙端口分流器和雙端口串聯方法的參數。本文專門介紹阻抗測量和計算S21使用雙端口分流…

[deepseek] C語言頭文件與匯編實現討論

我想詢問一種代碼實現方式,使用C語言,例如main.c包含了自己編寫的庫文件abc.h,我想問的是:一、abc.h中是否可以有實現函數的代碼;二、abc.h中的函數是否可以在另一個后綴為asm的匯編文件中實現?非常好&…

`.cursorrules` 與 `.cursorcontext`:Cursor AI 編程助手時代下的“雙軌配置”指南

.cursorrules 與 .cursorcontext:AI 編程助手時代下的“雙軌配置”指南關鍵詞:Cursor、AI 編程、上下文管理、開發規范、技術治理 適合讀者:前端 / 全棧工程師、技術負責人、AI 輔助編程實踐者1. 為什么又多了兩個“點”文件? 隨著…

XR 和 AI 在 Siggraph 2025 上主導圖形的未來,獲取gltf/glb格式

Meta 的 Boba 和 Tiramisu XR 耳機(來源:Meta) Siggraph 2025 今年重返不列顛哥倫比亞省溫哥華,慶祝《玩具總動員》誕生 30 周年和視頻游戲實時渲染 20 周年。雖然 Siggraph 需要時間來欣賞過去,但它更多的是展望未來…

在 Ubuntu 22.04 系統(CUDA 12.9)中,通過本地DEB 包安裝 cuDNN 9.13.0 的方法步驟

以下是在 Ubuntu 22.04 系統(CUDA 12.9)中,通過本地單個 DEB 包安裝 cuDNN 9.13.0 的完整步驟,核心包含 GPG 密鑰配置與包安裝驗證,確保每一步可執行。 一、安裝前核心檢查(必做) 確保系統已滿足基礎條件,避免安裝失敗: 驗證 CUDA 版本:打開終端執行命令,確認當前…

Element 中 upload 編輯回顯文件上傳信息技巧

文章目錄需求分析需求 upload 編輯狀態下回顯已上傳的文件信息 分析 添加fileList <el-uploadstyle"width: 100%"ref"uploadRef"class"upload-demo"action"/prod-api/jc/files/upload"multiple:limit"1":on-success&q…

php簡介(第一天打卡)

一.php簡介 1.什么是php&#xff1f; 1.1 Php 為什么叫這個名字&#xff1f; Personal home page 最開始用于個人主頁建站 后更名為 hypertext preprocessor 超文本預處理 1.2 php是屬于哪種語言&#xff1f; 后端語言 &#xff08;從開發角度分類&#xff09; 服務端語言…

Android 車聯網——車載儀表屏開發(二十六)

通常汽車啟動后需要快速顯示儀表,而車載娛樂系統所在的Android系統,啟動是比較耗時的,所以通常儀表系統會做在一個小型輕量化的系統內,從而達到快速啟動的效果,最終實現汽車一發動,就立刻能顯示出儀表必須顯示的各項內容。 一、儀表功能介紹 1、儀表的發展 機械儀表:通…

RL--RLHF--PPO--GRPO--DPO速通

參考視頻&#xff1a;1小時速通 - 從強化學習到RLHF - 簡介_嗶哩嗶哩_bilibili 強化學習RL RL的核心就是智能體Agent 與 環境Environment的交互。 狀態&#xff08;State&#xff0c;s&#xff09;&#xff1a;環境在某一時刻的描述&#xff0c;表示當前情境。動作&#xff0…

hardhat 項目目錄介紹

使用 npx hardhat init初始化一個 Hardhat 項目后&#xff0c;會生成一個結構清晰的目錄&#xff0c;每個部分都有其特定用途。下面是一個表格匯總了主要的目錄和文件及其作用&#xff0c;方便你快速了解&#xff1a;contracts/??存放項目的 ??Solidity 智能合約源代碼??…

9.11網編項目——UDP網絡聊天

服務器端#include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <errno.h> #include <unistd.h> #include <25061head.h> #d…

第3節-使用表格數據-數據庫設計

摘要: 在本教程中&#xff0c;你將學習如何為自己的應用程序設計 PostgreSQL 數據庫。 業務需求 我們將為一個簡單的庫存管理系統設計數據庫。 讓我們從業務需求開始&#xff1a; “我們的庫存管理系統使倉庫用戶能夠高效管理多個倉庫的庫存。” 它簡化了產品管理&#xff0c;使…

Linux下清理磁盤空間——df 磁盤占用100%,du占用很少空間的原因

背景 一臺測試服務器&#xff0c;/data磁盤大小為300G&#xff0c;時不時就滿了&#xff0c;通過df命令查看300G基本全用了&#xff0c;use 100%。但是進到/data目錄中通過du 命令查看&#xff0c;也就用了20個G左右&#xff0c;怎么都對不上。如何清理都沒有釋放太多空間。查看…

分鐘級長視頻生成迎來“記憶革命”,7倍成本降低,2.2倍端到端生成速度提升!|斯坦福字節

論文鏈接&#xff1a;https://arxiv.org/pdf/2508.21058 項目鏈接&#xff1a;https://primecai.github.io/moc/亮點直擊提出了一種自適應上下文混合&#xff08;Adaptive Mixture of Contexts&#xff0c;MoC&#xff09;框架&#xff0c;該框架學習將每個查詢路由到視頻序列中…

JavaScript 設計模式概覽

1. 設計模式是什么? 設計模式是開發中解決常見問題的經典方案。設計模式并非具體代碼&#xff0c;而是解決問題的通用解決方案&#xff0c;幫助開發者避免重復造輪子&#xff0c;提升代碼的可維護性、可擴展性。 2. 設計模式的歷史 設計模式起源于建筑領域&#xff0c;由克…

(九)Spring Cloud Alibaba 2023.x:微服務接口文檔統一管理與聚合

目錄 前言 準備 實踐 網關服務配置 1.pom.xml 引入 webflux 版本 springboc 依賴 2.application-dev.yml 配置 springboc 多服務地址 3.application-dev.yml 配置springboc 文檔路由 4.網關過濾器AuthFilter.class 中放行 springboc 訪問路徑 業務服務配置 1.pom.xml…

在Cursor里安裝極其好用的Mysql Database Client 插件

&#x1f4f8; 插件界面展示 圖片1&#xff1a;插件主界面和連接配置圖片2&#xff1a;數據編輯和查詢結果展示&#x1f3af; 核心優勢 1. 直接編輯數據 - 像DataGrip一樣強大 ? 點擊即編輯: 直接雙擊數據單元格&#xff0c;立即進入編輯模式? 實時保存: 編輯完成后按 Enter …