QT:模型视图代理

Qt Model/View/Delegate(MVD)框架,它是 Qt 中用于实现数据显示和编辑的一种架构模式,主要由模型(Model)、视图(View)和委托(Delegate)三部分组成,以下是对其概念的详细介绍:

模型(Model)

角色:模型是 MVD 框架的核心部分,主要负责存储和管理数据。它提供了一种统一的接口,用于访问和操作各种类型的数据,如数组、列表、表格数据等,而不依赖于具体的数据存储方式。
功能:模型负责提供数据给视图进行显示,同时也处理来自视图的用户交互操作,如数据的插入、删除、修改等。它通过信号和槽机制与视图和委托进行通信,当数据发生变化时,模型会发出信号通知视图进行更新。
常用类:在 Qt 中,有多种模型类可供使用,如QStandardItemModel用于处理标准的列表和表格数据,QFileSystemModel用于处理文件系统相关的数据,QSqlTableModel用于与数据库表进行交互等。

视图(View)

角色:视图主要负责数据的可视化展示,它从模型中获取数据,并以特定的方式将数据呈现给用户,如以列表、表格、树状等形式显示。
功能:视图负责接收用户的输入操作,如鼠标点击、键盘输入等,并将这些操作转换为对模型的请求。例如,当用户在表格视图中点击某个单元格时,视图会将这个操作传递给模型,以便模型进行相应的处理。同时,视图会根据模型发出的信号来更新自身的显示,以反映数据的变化。
常用类:Qt 提供了多种视图类,如QListView用于显示列表数据,QTableView用于显示表格数据,QTreeView用于显示树状结构数据等。

委托(Delegate)

角色:委托用于控制数据在视图中的编辑和显示方式,它提供了一种自定义数据显示和编辑行为的机制。
功能:在视图中,当用户需要编辑数据时,委托会提供相应的编辑组件,如文本框、下拉列表等,让用户进行编辑。委托还可以对用户输入的数据进行验证和格式化处理,确保数据的合法性和一致性。
常用类:Qt 中常用的委托类是QStyledItemDelegate,它提供了基本的委托功能。用户可以通过继承QStyledItemDelegate类来实现自定义的委托,以满足特定的需求。

QAbstractItemModel

在 Qt 中,QAbstractItemModel 是所有模型类的抽象基类,它为数据模型提供了一个通用的接口,使得数据可以被不同的视图(如 QListView、QTableView、QTreeView 等)显示和操作。从 QAbstractItemModel 派生出了许多具体的模型类

QStandardItemModel

用途:QStandardItemModel 是一个通用的模型类,用于存储标准项(QStandardItem)的数据。它可以处理列表、表格和树状结构的数据,非常适合简单的数据管理和显示。

#include <QApplication>
#include <QStandardItemModel>
#include <QTableView>
#include <QDebug>// 槽函数,用于处理数据更改信号
void printCellData(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles) {Q_UNUSED(roles);// 将 model 声明为 const QAbstractItemModel* 类型const QAbstractItemModel *model = topLeft.model();// 遍历更改的单元格范围for (int row = topLeft.row(); row <= bottomRight.row(); ++row) {for (int col = topLeft.column(); col <= bottomRight.column(); ++col) {QModelIndex index = model->index(row, col);QVariant data = model->data(index);qDebug() << "Row:" << row << "Column:" << col << "Data:" << data.toString();}}
}int main(int argc, char *argv[]) {QApplication a(argc, argv);// 创建一个 QStandardItemModel,有 3 行 2 列QStandardItemModel model(3, 2);// 设置表头model.setHorizontalHeaderLabels({"Name", "Age"});// 设置单元格数据QStandardItem *item1 = new QStandardItem("Alice");model.setItem(0, 0, item1);QStandardItem *item2 = new QStandardItem("25");model.setItem(0, 1, item2);// 创建一个表格视图并设置模型QTableView tableView;tableView.setModel(&model);// 连接模型的数据更改信号到槽函数QObject::connect(&model, &QStandardItemModel::dataChanged, printCellData);tableView.show();return a.exec();
}

在这里插入图片描述

QFileSystemModel

用途:QFileSystemModel 用于表示文件系统的目录和文件结构。它可以方便地在视图中显示文件系统的内容,支持文件和文件夹的浏览、排序等操作。

#include <QApplication>
#include <QFileSystemModel>
#include <QTreeView>
#include <QDebug>// 槽函数,用于处理树状视图的点击事件
void printClickedItemInfo(const QModelIndex &index) {const QFileSystemModel *model = qobject_cast<const QFileSystemModel*>(index.model());if (model) {// 获取文件或文件夹的路径QString filePath = model->filePath(index);// 获取文件或文件夹的名称QString fileName = model->fileName(index);// 判断是文件还是文件夹bool isDir = model->isDir(index);qDebug() << "Clicked Item Information:";qDebug() << "Name:" << fileName;qDebug() << "Path:" << filePath;qDebug() << "Is Directory:" << (isDir ? "Yes" : "No");}
}int main(int argc, char *argv[]) {QApplication a(argc, argv);// 创建一个 QFileSystemModelQFileSystemModel model;// 设置根路径model.setRootPath(QDir::homePath());// 创建一个树状视图并设置模型QTreeView treeView;treeView.setModel(&model);// 设置显示的根目录treeView.setRootIndex(model.index(QDir::homePath()));// 连接树状视图的 clicked 信号到槽函数QObject::connect(&treeView, &QTreeView::clicked, printClickedItemInfo);treeView.show();return a.exec();
}

在这里插入图片描述

QSqlTableModel

用途:QSqlTableModel 用于与数据库中的单个表进行交互。它提供了一种简单的方式来显示、编辑和管理数据库表中的数据。

#include <QApplication>
#include <QSqlDatabase>
#include <QSqlTableModel>
#include <QTableView>
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>// 创建表并插入示例数据
void setupDatabase(QSqlDatabase &db) {QSqlQuery query(db);// 创建 people 表if (!query.exec("CREATE TABLE IF NOT EXISTS people (""id INTEGER PRIMARY KEY AUTOINCREMENT, ""name TEXT, ""age INTEGER)")) {qDebug() << "Table creation error:" << query.lastError().text();return;}// 插入示例数据if (!query.exec("INSERT INTO people (name, age) VALUES ('Alice', 25)")) {qDebug() << "Data insertion error:" << query.lastError().text();}if (!query.exec("INSERT INTO people (name, age) VALUES ('Bob', 30)")) {qDebug() << "Data insertion error:" << query.lastError().text();}
}int main(int argc, char *argv[]) {QApplication a(argc, argv);// 连接数据库QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");db.setDatabaseName("test.db");if (!db.open()) {qDebug() << "Database open error:" << db.lastError().text();return 1;}// 设置数据库,创建表并插入数据setupDatabase(db);// 创建一个 QSqlTableModelQSqlTableModel model;// 设置要操作的表名model.setTable("people");// 选择表中的数据model.select();// 创建一个表格视图并设置模型QTableView tableView;tableView.setModel(&model);tableView.show();return a.exec();
}

setupDatabase 函数:
该函数接受一个 QSqlDatabase 引用作为参数,用于在数据库中创建表并插入示例数据。
使用 QSqlQuery 执行 SQL 语句,CREATE TABLE IF NOT EXISTS 用于创建 people 表,如果该表不存在的话。
接着使用 INSERT INTO 语句插入两条示例数据。
main 函数:
连接到 SQLite 数据库 test.db,如果打开失败则输出错误信息并退出程序。
调用 setupDatabase 函数,创建表并插入示例数据。
创建 QSqlTableModel 并设置要操作的表名为 people,然后调用 select() 方法从表中选择数据。
创建 QTableView 并将模型设置给它,最后显示表格视图。
在这里插入图片描述

QSqlQueryModel

用途:QSqlQueryModel 用于执行 SQL 查询并显示查询结果。它是一个只读模型,不支持直接编辑数据,但可以方便地显示数据库查询的结果。

#include <QApplication>
#include <QSqlDatabase>
#include <QSqlQueryModel>
#include <QTableView>
#include <QSqlError>
#include <QDebug>int main(int argc, char *argv[]) {QApplication a(argc, argv);// 连接数据库QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");db.setDatabaseName("test.db");if (!db.open()) {qDebug() << "Database open error:" << db.lastError().text();return 1;}// 创建一个 QSqlQueryModelQSqlQueryModel model;// 执行 SQL 查询model.setQuery("SELECT * FROM people");// 创建一个表格视图并设置模型QTableView tableView;tableView.setModel(&model);tableView.show();return a.exec();
}

在这里插入图片描述

功能特点

  1. QSqlQueryModel
    只读性:QSqlQueryModel 是一个只读模型,它主要用于执行 SQL 查询并显示查询结果,不支持直接对数据进行编辑、插入或删除操作。这是因为它设计的初衷是简单地呈现查询到的数据,不提供修改数据的接口,以保证数据的安全性和一致性。
    灵活性:它非常灵活,可以执行任意的 SQL 查询语句,无论是简单的 SELECT 查询,还是复杂的多表连接查询、带有条件和排序的查询等,都能轻松应对。你可以根据自己的需求构造不同的 SQL 查询语句,然后将结果显示在视图中。
    数据处理:QSqlQueryModel 只是简单地将查询结果存储在模型中,并提供给视图进行显示,不负责对数据进行额外的处理或维护。例如,它不会跟踪数据的修改状态,也不会自动更新数据库中的数据。
  2. QSqlTableModel
    可编辑性:QSqlTableModel 支持对数据进行编辑、插入和删除操作。它提供了一系列的接口,如 setData() 用于修改数据,insertRows() 用于插入新行,removeRows() 用于删除行等。当你对模型中的数据进行修改后,可以调用 submitAll() 或 revertAll() 方法来提交或撤销这些修改,并且这些修改会自动反映到数据库中。
    单表操作:QSqlTableModel 主要用于与数据库中的单个表进行交互,它只能操作一个指定的表。在使用时,你需要通过 setTable() 方法指定要操作的表名,然后可以对该表中的数据进行各种操作。
    数据同步:QSqlTableModel 会自动跟踪数据的修改状态,确保模型中的数据与数据库中的数据保持同步。当你对模型中的数据进行修改后,调用 submitAll() 方法时,它会将这些修改应用到数据库中;调用 revertAll() 方法时,会将模型中的数据恢复到上次从数据库中读取的状态。

使用场景

  1. QSqlQueryModel
    当你只需要显示数据库中的数据,而不需要对数据进行编辑时,可以使用 QSqlQueryModel。例如,显示数据库中的统计报表、查询结果列表等。
    当你需要执行复杂的 SQL 查询,并且不需要对查询结果进行修改时,QSqlQueryModel 是一个很好的选择。因为它可以执行任意的 SQL 查询,并且能够快速地将查询结果显示在视图中。
  2. QSqlTableModel
    当你需要对数据库中的单个表进行数据的编辑、插入和删除操作时,应该使用 QSqlTableModel。例如,开发一个数据库管理系统,需要对用户信息表进行增删改查操作,就可以使用 QSqlTableModel。
    当你需要确保模型中的数据与数据库中的数据保持同步时,QSqlTableModel 能够很好地满足需求。它会自动处理数据的更新和同步,减少了开发者的工作量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/70903.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PowerShell 执行策略:fnm管理软件安装nodejs无法运行npm,错误信息:about_Execution_Policies

通过fnm管理软件安装NodeJS后添加环境变量依然无法执行npm,提示无法加载文件&#xff0c;错误如下&#xff1a; PowerShell 执行策略简介&#xff1a; PowerShell 执行策略是一项安全功能&#xff0c;用于控制 PowerShell 加载配置文件和运行脚本的条件。 此功能有助于防止恶…

drupal的翻译集添加后如何起作用

在 Drupal 中&#xff0c;翻译集&#xff08;Translation Set&#xff09;添加后&#xff0c;需要进行 正确的配置和激活 才能生效。以下是确保翻译集&#xff08;如界面翻译、内容翻译、配置翻译等&#xff09;生效的步骤&#xff1a; 1. 确保已启用多语言模块 在 Drupal 8/9…

利用 Windows Terminal 和 SSH Config 简化 Linux 服务器管理

在日常的 Linux 服务器管理中&#xff0c;频繁登录不同的主机是一项常见任务。传统方法可能需要记住复杂的 IP 地址、用户名和端口&#xff0c;或者依赖如 Xshell 这样的第三方工具。但借助 Windows Terminal 和 SSH 的 .ssh/config 文件&#xff0c;我们可以打造一个高效、免费…

【算法 位运算】801. 二进制中1的个数

题目 801. 二进制中1的个数 思路 定义lowbit函数&#xff0c;能够找到二进制最后一个1&#xff0c;找到最后一个1就删掉&#xff0c;计数加1&#xff0c;以此类推&#xff0c;直到找不到最后一个1。 代码 #include<iostream> using namespace std; int lowbit(int x…

DeepSeek-R1-671B大模型满血版私有化部署高可用教程-SparkAi系统集成图文教程

DeepSeek官网服务器繁忙的主要原因是由于用户数量激增导致的服务器资源紧张。‌为了解决这一问题&#xff0c;DeepSeek团队已经暂停了API服务充值&#xff0c;以避免对用户造成业务影响。目前&#xff0c;存量充值金额仍可继续调用&#xff0c;但充值功能暂时不可用‌。 DeepSe…

C++:指针数组与数组指针

文章目录 概述1. 什么是指针数组 (Array of Pointers)定义&#xff1a;示例&#xff1a;解释&#xff1a; 2. 什么是数组指针 (Pointer to Array)定义&#xff1a;示例&#xff1a;解释&#xff1a; 关键区别例子对比指针数组&#xff1a;数组指针&#xff1a; 总结 概述 指针…

StableDiffusion本地部署 2

StableDiffusion本地部署 为了做这个事&#xff0c;这是第5篇文章了&#xff0c;可谓是做足了准备。开干&#xff01; 强烈建议把我之前发的文章看一看&#xff0c;不然你会有点迷迷糊糊的。 整体思路 捋一捋思路&#xff1a; 下载三个东西&#xff0c;webui&#xff0c;py…

【项目管理】基于 C 语言的 QQ 聊天室实现(TCP + 多线程 + SQLite3)

基于 C 语言的 QQ 聊天室(TCP + 多线程 + SQLite3) 项目功能基础功能: 登录、注册、添加好友、私聊、创建群聊、群聊扩展功能: 删除好友、注销账号、好友在线状态、群管理(拉人/踢人)、VIP 特权、邮件通知等 功能介绍:模拟QQ聊天客户端:登录界面:1、登录2、注册 //将用…

无人机遥控器的亮度 和 两个工作频率

工作频率 2.4000-2.4835 GHz &#xff0c; 5.725-5.850 GHz 1.这是一个无人机的遥控器的两个工作频率&#xff0c;为什么会有两个工作频率&#xff1f; 无人机的遥控器采用双频段设计&#xff08;2.4GHz 和 5.8GHz&#xff09;&#xff0c;主要是为了解决以下问题并优化性…

drupal可以自动将测试环境的网页部署到生产环境吗

在 Drupal 中&#xff0c;自动将测试环境的网页部署到生产环境通常是通过设置合适的开发和部署流程来实现的。这种自动化部署过程通常涉及以下几个步骤&#xff1a; 1. 版本控制&#xff08;Git&#xff09; 为了保证测试环境和生产环境的一致性&#xff0c;首先需要使用 Git…

SOC-ATF 安全启动BL1流程分析(1)

一、ATF 源码下载链接 1. ARM Trusted Firmware (ATF) 官方 GitHub 仓库 GitHub 地址: https://github.com/ARM-software/arm-trusted-firmware 这是 ATF 的官方源码仓库&#xff0c;包含最新的代码、文档和示例。 下载方式&#xff1a; 使用 Git 克隆仓库&#xff1a; git…

《模拟器过检测教程:Nox、雷电、Mumu、逍遥模拟器 Magisk、LSposed 框架安装与隐藏应用配置》

一、夜神模拟器 (Nox) 过检测 使用版本&#xff1a;7.0.6.2&#xff08;20250209&#xff09; 1. 准备工作 将需要用到的应用放入文件夹&#xff1a; C:\Users\Administrator.DESKTOP-I5V50SS\Nox_share\Download 2. 安装面具鸭&#xff08;Magisk&#xff09; 在模拟器下…

.Net Core Visual Studio NuGet.Config 配置参考

Visual Studio 2022 NUGET NU1301 无法加载源 基础连接已关闭&#xff1a;无法建立SSL / TLS安全通道的信任关系&#xff1b;根据验证过程&#xff0c;远程证书无效&#xff0c;参考文章&#xff1a;https://blog.csdn.net/hefeng_aspnet/article/details/145780081 NuGet 行为…

同价位usb网卡与pcie网卡网速差距实测 热点测试

选用两款价位在75上下的网卡 2.4G usb&#xff1a; 2.4G pcie网卡&#xff1a; 5G PCIE 5G USB

DVWA -第二关-命令执行

这里是个ping命令的提交框 我们在输入ping命令的时候&#xff0c;同时执行其他命令操作 low 输入127.0.0.||ipconfig 消除乱码的方法&#xff1a;修改dvwaPage.inc.php文件中的”charsetutf-8”&#xff0c;修改”charsetGB2312” 可以显示出来&#xff0c;初级没有过滤 m…

通信方式汇总

在计算机网络和通信领域,通信方式指的是数据在网络中传输的方式和机制。不同的通信方式适用于不同的应用场景和需求。以下是几种常见的通信方式: 1. 同步通信与异步通信 同步通信: 数据传输是按固定时钟周期进行的,发送方和接收方需要保持同步。适用于需要严格时间同步的场…

类和对象——const修饰的类的对象和函数

const修饰的类的对象和函数 const成员函数和const对象1 const成员函数2 调用关系3 const在成员函数中的位置4 取地址&及const取地址操作符重载 const成员函数和const对象 1 const成员函数 将const修饰的“成员函数”称之为const成员函数&#xff0c;const修饰类成员函数&…

【DeepSeek-R1背后的技术】系列十三:归一化方式介绍(BatchNorm, LayerNorm, Instance Norm 和 GroupNorm)

【DeepSeek-R1背后的技术】系列博文&#xff1a; 第1篇&#xff1a;混合专家模型&#xff08;MoE&#xff09; 第2篇&#xff1a;大模型知识蒸馏&#xff08;Knowledge Distillation&#xff09; 第3篇&#xff1a;强化学习&#xff08;Reinforcement Learning, RL&#xff09;…

高压风机专用32位单片机MM32SPIN080G

专为高压风机量身打造的32位高性能单片机&#xff0c;拥有卓越的处理性能和丰富的接口资源&#xff0c;能够应对工业级应用的严苛要求。 RAMSUN高性能单电机控制SOC单片机——32位MM32SPIN080G&#xff0c;基于Cortex-M0内核构建&#xff0c;集成了200V三相N沟道栅极驱动器。它…

计算机毕设-基于springboot的融合多源高校画像数据与协同过滤算法的高考择校推荐系统的设计与实现(附源码+lw+ppt+开题报告)

博主介绍&#xff1a;✌多个项目实战经验、多个大型网购商城开发经验、在某机构指导学员上千名、专注于本行业领域✌ 技术范围&#xff1a;Java实战项目、Python实战项目、微信小程序/安卓实战项目、爬虫大数据实战项目、Nodejs实战项目、PHP实战项目、.NET实战项目、Golang实战…